Relrin
Relrin

Reputation: 790

Define vector with tuple of any type

I'm trying to define a custom structure with a field that can be a std::vec::Vec with any type of element:

use std::vec::Vec;

#[derive(Debug, PartialEq)]
pub struct BertDictionary {
    data: Vec<(Any, Any)>  // not work also with Vec<(_, _)>
}

When compiling, this generates a E0308 error which means the compiler is unable to infer the concrete type. Is is possible to define such a structure?

As an example, I'm going to use this vector when each element may be represented like (name, "user"), (id, 1) and so on.

Upvotes: 1

Views: 1193

Answers (1)

allTwentyQuestions
allTwentyQuestions

Reputation: 1240

Any is a trait, not a concrete type, so you need to add a generic type parameter to the struct.

struct BertDirectory<T: Any> {
    data: Vec<T>
}

You might also want to ensure that T is also something that implements Debug and PartialEq. This isn't required to compile, but would be if you want to ensure that BertDirectory always implements those traits. Otherwise, it will only implement Debug when T does so.

struct BertDirectory<T: Any + Debug + PartialEq> {
    data: Vec<T>
}

Even given both of those things I don't know that this will give you what you really want because data will still be constrained to hold a single type. T can only ever represent a single type per instance of the struct.

If you need data to store values of different types, you might instead want to look into using trait objects instead, which is Rust's way of using vTables:

pub trait MyTrait: Debug {
    // you can still use Any by doing MyTrait: Any + Debug
    // Note that you won't be able to derive PartialEq for your trait 
    // because PartialEq can't be made into a TraitObject

    // can also define whatever methods you would want on your data, which
    // might be preferable to using Any, if possible
}

pub struct BertDirectory<T: MyTrait>{
    data: Vec<(Box<MyTrait>, Box<MyTrait>)>
}

That way the concrete type of T would not need to be known at compile time. Each element in data could be of a different concrete type and the correct methods would be called automatically. You would not be able to derive PartialEq, though, so you'd just have to implement that yourself.

Upvotes: 3

Related Questions