简体   繁体   中英

How to create a Vec of unit structs that implement sized trait?

I want to be able to create a Vec of unit structs that implement a sized trait (preferably without using a Box<T> ).

Here is what I want to be able to do, but It fails and says that ProgrammingLanguage cannot be made into a trait object:

struct Python;
struct Rust;

trait ProgrammingLanguage: Sized {
    fn say_hello_world() -> ();
}

impl ProgrammingLanguage for Python {...}
impl ProgrammingLanguage for Rust {...}

// Fails because ProgrammingLanguage cannot be made into a trait object
let foo = Vec::<ProgrammingLanguage>::from([Python, Rust]);

The Sized trait would not help you here. All it can guarantee is that any particular implementation of the trait is sized, ie that you can implement it on [u8] or dyn OtherTrait ; but the dyn ProgrammingLanguage itself is always unsized, by definition. The reason for this is quite simple: size of the trait object is defined as the size of an original type, and there's no way to statically guarantee that every type implementing the trait would have the same size.

However, there's no real reason to avoid Box . As was mentioned in the comments, Box<UnitStruct> is essentially just a never-dereferenced dangling pointer, without any allocation at all:

struct Rust;

fn main() {
    println!("{:p}", Box::new(Rust)); // prints `0x1`
}

When you convert it to the trait object, pointer itself doesn't change - compiler just adds the vtable pointer, which is necessary for any operations with trait objects anyway.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM