我正在尝试用 Rust 编写一个函数来构建不同类型的对象(相同特征的所有实现)但是我遇到了麻烦,不明白我是在尝试做一些非法的事情还是只是没有掌握正确的语法. 这是一个玩具示例,未编译(animal_factory 函数的三个变体均未编译):
enum Error {
UnknownAnimal,
}
trait Animal {
fn bark(&self);
}
struct Dog {}
impl Dog {
fn new() -> Result<Dog, Error> {
Ok(Dog {})
}
}
impl Animal for Dog {
fn bark(&self) {
println!("Bau! Bau!");
}
}
struct Cat {}
impl Cat {
fn new() -> Result<Cat, Error> {
Ok(Cat {})
}
}
impl Animal for Cat {
fn bark(&self) {
println!("Meow! Meow!");
}
}
/*
fn animal_factory(kind: &str) -> Result<impl Animal, Error> {
match kind {
"cat" => Cat::new(),
"dog" => Dog::new(),
_ => Err(Error::UnknownAnimal),
}
}
*/
/*
fn animal_factory(kind: &str) -> Result<impl Animal, Error> {
match kind {
"cat" => {
return Cat::new();
},
"dog" => {
return Dog::new();
},
_ => {
return Err(Error::UnknownAnimal);
},
}
}
*/
fn animal_factory(kind: &str) -> Result<impl Animal, Error> {
if kind == "cat" {
Cat::new()
} else if kind == "dog" {
Dog::new()
} else {
Err(Error::UnknownAnimal)
}
}
fn main() {
let x = animal_factory("cat").unwrap();
let y = animal_factory("dog").unwrap();
}
有什么见解吗?也许我需要把东西装箱?
谢谢!
impl Animal
和
Cat
),Dog
将不起作用,即使两者都实现了Animal
。这是 Rust 中的类型不匹配。您需要使用的是 trait objects,用 dyn Animal
注释。 Trait 对象是动态调整大小的,因此我们需要将它们包装成 Box
或其他类型的智能指针或引用:
fn animal_factory(kind: &str) -> Result<Box<dyn Animal>, Error> {
if kind == "cat" {
Ok(Box::new(Cat::new()?))
} else if kind == "dog" {
Ok(Box::new(Dog::new()?))
} else {
Err(Error::UnknownAnimal)
}
}