我有两个结构,Dog
和Cat
:
struct Dog {
weight: f64
}
struct Cat {
weight: f64
}
和两个特征MakesSound
和HasWeight
trait MakesSound {
fn make_sound(&self);
}
impl MakesSound for Dog {
fn make_sound(&self) {
println!("Bark bark!");
}
}
impl MakesSound for Cat {
fn make_sound(&self) {
println!("Go away.");
}
}
trait HasWeight {
fn get_weight(&self) -> f64;
}
impl HasWeight for Dog {
fn get_weight(&self) -> f64 { self.weight }
}
impl HasWeight for Cat {
fn get_weight(&self) -> f64 { self.weight }
}
我希望能够将它们存储在异构Vec
中,然后再利用它们的特征
trait Animal: MakesSound + HasWeight {}
impl<T: MakesSound + HasWeight> Animal for T {}
fn main() {
let dog = Dog{ weight: 45.0 };
let cat = Cat{ weight: 12.0 };
let animals: Vec<&Animal> = vec![&dog, &cat];
for animal in animals {
animal.make_sound();
println!("{}", animal.get_weight());
//print_weight(animal as &HasWeight);
}
}
如何定义类型为
的print_weight
函数
fn print_weight(x: &HasWeight);
所以我的功能需要尽可能少的信息,但我的Vec
会尽可能多地存储信息?
取消注释上述行所得的错误是
error: non-scalar cast: `&Animal` as `&HasWeight`
答案 0 :(得分:2)
这是一个print_weight
函数,它对具有HasWeight
特征的类型是通用的。不幸的是,我对Rust缺乏经验,告诉你为什么额外的?Sized
特征限制是必要的。
fn print_weight<T: HasWeight + ?Sized>(thing: &T) {
println!("{}", thing.get_weight());
}
这可以在你的循环中调用而不需要任何强制转换:print_weight(animal)
。