这个周末开始学习生锈,我正在尝试在我的课堂上写一个私有的助手方法来查找一些内部值,但是事实证明这很复杂。我有一些实现特质的结构:
trait Animal {}
struct Dog {}
impl Dog for Animal{}
struct Cat{}
impl Cat for Animal{}
以及一个容纳多种动物变种的容器:
struct Person {
my_dog: Dog,
my_cat: Cat
}
我想做的是编写一个帮助程序,查找适当的动物,如下所示:
impl Person {
fn look_up_animal(&self, animal_name: &str) -> Box<&dyn Animal> {
match animal_name {
"dog" => Box::from(&self.my_dog),
"cat" => Box::from(&self.my_cat)
}
}
}
不幸的是,我无法弄清楚如何为此做类型。上面使用引用和 Box
的版本给出了类似“预期struct Box<&dyn Animal>
但得到struct Box<&Dog>
的错误,因此我不确定如何转换常规值变成dyn
值。
答案 0 :(得分:5)
您想要的内容的完全明确的版本
impl Person {
fn look_up_animal(&self, animal_name: &str) -> Option<Box<&dyn Animal>> {
match animal_name {
"dog" => Some(Box::from(&self.my_dog as &dyn Animal)),
"cat" => Some(Box::from(&self.my_cat as &dyn Animal)),
_ => None,
}
}
}
Rust能够强制对特征对象进行一层引用,但是两层引用(Box
和&
)都会使其崩溃。 (在Box
中包含引用也会触发clippy
警告。)这提出了另一种解决方案。
impl Person {
fn look_up_animal(&self, animal_name: &str) -> Option<&dyn Animal> {
match animal_name {
"dog" => Some(&self.my_dog as &dyn Animal),
"cat" => Some(&self.my_cat as &dyn Animal),
_ => None,
}
}
}
这一次,由于仅存在一层引用,因此不需要显式强制转换as &dyn Animal
。
impl Person {
fn look_up_animal(&self, animal_name: &str) -> Option<&dyn Animal> {
match animal_name {
"dog" => Some(&self.my_dog),
"cat" => Some(&self.my_cat),
_ => None,
}
}
}
注意:我添加了Option
,以便在animal_name
不是"dog"
或"cat"
时有返回的内容。您也可能会惊慌或默认使用其他实现Animal
的东西。
答案 1 :(得分:-4)
<input type="file" />
完整解决方案playground