прежде всего обязательное «Я новичок в 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?
}
}
Playground
Я понимаю, что это может быть глупым вопросом или показать, что я «все еще застрял в мышлении, отличном от Rust», но я нахожусь здесь как бы в тупике и мне нужна лишь небольшая помощь.