=== edit at 2018-04-28 10:17AM ===
Thanks for your answers, but when I follow your answers using Box<>
, I found a situation where it won't work still.
https://play.rust-lang.org/?gist=211845d953cd9012f6f214aa5d81332d&version=stable&mode=debug
Bug info is:
error[E0038]: the trait `Entity` cannot be made into an object
--> src/main.rs:20:5
|
20 | entities: Vec<Box<Entity>>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Entity` cannot be made into an object
|
= note: the trait cannot require that `Self : Sized`
So I wonder what is cannot be made into an object
? How can I fix the problem?
=== original answer ===
I want to implement a hierarchical structure like Java's interface/abstract class with a normal class:
trait Entry {
fn new() -> Entry;
}
struct EntryA {}
impl Entry for EntryA {
fn new() -> EntryA {
// I want to return EntryA rather Entry here, just like dynamic dispatch in Java
}
}
struct EntryB {}
impl Entry for EntryB {
fn new() -> EntryB {
// Another Entry struct
}
}
Now I want to create a Vec
or an array containing the Entry
s:
fn create_an_array() -> [Something to write here] {
let mut vec: Vec<Entry> = vec![];
let ea = EntryA::new();
let eb = EntryB::new();
vec.push(ea);
vec.push(eb);
vec
}
When I use the Vec
created by create_an_array()
, all the elements I get can just show the Entry
facade, rather than the subclass in detail.
However, the main problem is that when overriding the function, Rust considers not only the parameters but also the return type (Why you do that, Rust?!), so I cannot override new()
in EntryA
or EntryB
because the function has a different return type than the Entry
trait.
How do I deal with the problem of dynamic dispatch?