Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.3k views
in Technique[技术] by (71.8m points)

rust - Is it possible to have a heterogeneous vector of types that implement Eq?

I want a vector for elements that contain a trait such as Eq and I need heterogeneous vectors. For example:

let mut x: Vec<Eq> = Vec::new();

x.push(1);
x.push("hello")

I get an error message that says that Eq cannot be made into an object:

error[E0038]: the trait `std::cmp::Eq` cannot be made into an object
 --> src/main.rs:2:20
  |
2 |     let mut x: Vec<Eq> = Vec::new();
  |                    ^^ the trait `std::cmp::Eq` cannot be made into an object
  |
  = note: the trait cannot use `Self` as a type parameter in the supertrait listing

Is it possible to have a list of pointers to things I can compare regardless of their types?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Is it possible to have a list of pointers to things I can compare regardless of their types?

This doesn't make sense. How do you "compare" a String and a File or a Socket and a GuiWindowFontFamily?

The code has some minor issues as well, namely that it lacks any kind of indirection for the trait. See What is the best way to create a heterogeneous collection of objects? for a good overview of how to make a heterogeneous vector when not fighting object safety.

Speaking of object safety, there's a great blog series on the subject, which covers the details of the specific error you are getting.

So, what can we do? For starters, we can be more specific:

let mut x: Vec<Box<PartialEq<u8>>> = Vec::new();

This works because we are saying that everything in the vector can be compared to a u8, and there's not an open-ended infinite number of possibilities that each may be compared to.

You could also implement some trait that dictates how things should be compared, and then use that:

trait Silly {
    fn silly(&self) -> usize;
}

impl Silly for u8 {
    fn silly(&self) -> usize { *self as usize }
}

impl Silly for bool {
    fn silly(&self) -> usize { 1 }
}

fn main() {
    let mut x: Vec<Box<Silly>> = Vec::new();
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...