首先是强制性的“我是Rust的新手”:我是。
所以我有以下问题:
我有两个(或多个)数据结构,除了它们自己的行为外,它们都实现了一些常见的行为。我有这些结构(或更确切地说:“超类型”的结构)的列表,我需要访问它们的某些共享行为和某些个体行为。我的问题是:如何在Rust中做到这一点。
为了进一步说明我的问题,我提出了Kotlin和Rust之间的代码比较。Kotlin可以按我的意愿工作,Rust尚未(至今)。
在Kotlin中,代码可能如下所示(使用普通的旧继承抽象):
interface Animal {
fun eat()
fun sleep()
}
class Cat(val name: String) : Animal {
fun meow() { println("meow") }
override fun eat() { println("cat $name is eating fish(or lasagne)") }
override fun sleep() { println("cat $name sleeps inside") }
}
class Lion(val tag_id: Int) : Animal {
fun roar() { println("roar") }
override fun eat() { println("lion(tag=${tag_id} is eating gazelle") }
override fun sleep() { println("lion(tag=${tag_id} sleeps outside") }
}
var animals: MutableList<Animal> = ArrayList()
fun main() {
animals.add(Cat("Garfield"))
animals.add(Lion(12))
//later:
for (animal in animals) {
animal.sleep()
if (animal is Lion)
animal.roar()
}
}
在Rust中,我想到了以下代码(不允许使用'instance_of'类型的函数):
trait Animal {
fn eat(&self);
fn sleep(&self);
}
struct Cat {
name: String
}
impl Cat {
fn meow(&self) { println!("meow") }
}
impl Animal for Cat {
fn eat(&self) { println!("cat {} is eating fish(or lasagne)", self.name) }
fn sleep(&self) { println!("cat {} sleeps inside", self.name) }
}
struct Lion {
tag_id: usize
}
impl Lion {
fn roar(&self) { println!("roar") }
}
impl Animal for Lion {
fn eat(&self) { println!("lion(tag={}) is eating fish(or lasagne)", self.tag_id) }
fn sleep(&self) { println!("lion(tag={}) sleeps inside", self.tag_id) }
}
fn main() {
let animals:Vec<Box<dyn Animal>> = vec![
Box::new(Cat {name: "Garfield".to_string()}),
Box::new(Lion {tag_id: 12})
];
//later:
for animal in animals {
animal.sleep()
//HOW DO I ACCESS THE CONCRETE STRUCT HERE?
}
}
我意识到这可能是一个愚蠢的问题,或者表明我如何“仍然陷于非铁锈思维中”,但是我在这里有点像通行证,需要一点点坚持。
您可以尝试这样的事情
use std::any::Any;
trait Animal {
fn eat(&self);
fn sleep(&self);
fn as_any(&self) -> &dyn Any;
}
struct Cat {
name: String
}
impl Cat {
fn meow(&self) { println!("meow") }
}
impl Animal for Cat {
fn eat(&self) { println!("cat {} is eating fish(or lasagne)", self.name) }
fn sleep(&self) { println!("cat {} sleeps inside", self.name) }
fn as_any(&self) -> &dyn Any { self }
}
struct Lion {
tag_id: usize
}
impl Lion {
fn roar(&self) { println!("roar") }
}
impl Animal for Lion {
fn eat(&self) { println!("lion(tag={}) is eating fish(or lasagne)", self.tag_id) }
fn sleep(&self) { println!("lion(tag={}) sleeps inside", self.tag_id) }
fn as_any(&self) -> &dyn Any { self }
}
fn main() {
let animals:Vec<Box<dyn Animal>> = vec![
Box::new(Cat {name: "Garfield".to_string()}),
Box::new(Lion {tag_id: 12})
];
//later:
for animal in animals.iter() {
animal.sleep();
if let Some(animal) = animal.as_any().downcast_ref::<Lion>() {
animal.roar();
}
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句