假设以下Rust代码:
trait MyTrait {...}
struct MyStruct;
impl MyTrait for MyStruct {...}
impl MyStruct {
pub fn new() -> MyStruct { MyStruct{...} }
}
我能写:
let foo: MyStruct = MyStruct::new();
但我不能
let bar: MyTrait = MyStruct::new();
其他面向接口的编程语言可以做到这一点。我错过了什么吗?如何将各种对象传递给仅接受MyTrait
的方法?我是否需要使用“模板”,例如my_method<T: MyTrait>(param: T) {...}
?
答案 0 :(得分:1)
您不需要将bar
定义为MyTrait
对象。 (这甚至是错误的想法,因为生锈并没有真正具有继承性。将特征视为更像Java中的接口。在这种情况下,您似乎将MyTrait
视为超类MyStruct
)
你可以这样做
let bar = MyStruct::new();
然后只需将其传递给定义如下的函数:
fn my_method<T: MyTrait>(param: T) {...}
my_method(bar)
这是有效的,因为Rust会静态检查bar
MyStruct
类型是否实现了特征MyTrait
。
旁注:如果要创建特征对象的矢量,请检查this问题。
答案 1 :(得分:1)
这是因为特征可以被许多类型所强调,因此bar
的大小是未知的。但是,参考的大小将是已知的,因此以下工作。
trait MyTrait {}
struct MyStruct;
impl MyTrait for MyStruct {}
impl MyStruct {
fn new() -> Self {
MyStruct
}
}
fn main() {
let foo: MyStruct = MyStruct::new();
let bar: &MyTrait = &MyStruct::new();
}
请注意bar
不是MyTrait
,而是&MyTrait
,这称为indexed collections。