Kotlin 如何解决rust中的继承问题?
首先,我是新生锈的人:我是 因此,我有以下问题: 我有两个或两个以上的数据结构,它们除了实现自己的行为外,还实现了一些常见的行为。我有一个这些结构的列表,或者更确切地说:对于“超类型”,我需要访问它们的一些共享行为和它们的一些个人行为。 我的问题是:我如何在生锈的情况下做到这一点 为了进一步说明我的问题,我对Kotlin和Rust进行了代码比较。Kotlin按我的要求工作,Rust还没有 在Kotlin中,使用简单的旧继承抽象,代码可能如下所示:Kotlin 如何解决rust中的继承问题?,kotlin,inheritance,rust,Kotlin,Inheritance,Rust,首先,我是新生锈的人:我是 因此,我有以下问题: 我有两个或两个以上的数据结构,它们除了实现自己的行为外,还实现了一些常见的行为。我有一个这些结构的列表,或者更确切地说:对于“超类型”,我需要访问它们的一些共享行为和它们的一些个人行为。 我的问题是:我如何在生锈的情况下做到这一点 为了进一步说明我的问题,我对Kotlin和Rust进行了代码比较。Kotlin按我的要求工作,Rust还没有 在Kotlin中,使用简单的旧继承抽象,代码可能如下所示: interface Animal { f
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?
}
}
我意识到这可能是一个愚蠢的问题,或者说明我“仍然被困在不生锈的思维中”,但我在这里有点僵局,需要的只是一点帮助。试着用作文代替
trait Animal {
fn voicebox(&self) -> Voicebox;
}
enum Voicebox {
CatVoicebox, LionVoicebox
}
impl Voicebox {
fn make_sound(&self) {
match *self {
Voicebox::CatVoicebox => println!("meow"),
Voicebox::LionVoicebox => println!("roar!")
}
}
}
impl Animal for Cat {
fn voicebox(&self) -> Voicebox {
Voicebox::CatVoicebox
}
}
impl Animal for Lion {
fn voicebox(&self) -> Voicebox {
Voicebox::LionVoicebox
}
}
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();
match animal.voicebox() {
vb@Voicebox::LionVoicebox => vb.make_sound(),
_ => ()
}
}
}
试着用作文来代替
trait Animal {
fn voicebox(&self) -> Voicebox;
}
enum Voicebox {
CatVoicebox, LionVoicebox
}
impl Voicebox {
fn make_sound(&self) {
match *self {
Voicebox::CatVoicebox => println!("meow"),
Voicebox::LionVoicebox => println!("roar!")
}
}
}
impl Animal for Cat {
fn voicebox(&self) -> Voicebox {
Voicebox::CatVoicebox
}
}
impl Animal for Lion {
fn voicebox(&self) -> Voicebox {
Voicebox::LionVoicebox
}
}
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();
match animal.voicebox() {
vb@Voicebox::LionVoicebox => vb.make_sound(),
_ => ()
}
}
}
通过为每个子类型提供as_uu函数,可以实现类型检查条件:
trait Animal {
fn eat(&self);
fn sleep(&self);
fn as_roaring(&self)->Option<&dyn Roaring>;
fn as_meowing(&self)->Option<&dyn Meowing>;
}
.可以通过为每个子类型提供as_uu函数来实现类型检查条件:
trait Animal {
fn eat(&self);
fn sleep(&self);
fn as_roaring(&self)->Option<&dyn Roaring>;
fn as_meowing(&self)->Option<&dyn Meowing>;
}
.你可以试试这样的 使用std::any::any; 特征动物{ fn吃与自我; fn睡眠与自我; fn as_any&self->&dyn any; } 结构猫{ 名称:String } impl猫{ fn喵喵&self{println!喵喵} } 猫科动物{ fn eat&self{println!cat{}正在吃鱼或千层面,self.name} fn sleep&self{println!cat{}在里面睡觉,self.name} fn as_any&self->&dyn any{self} } 结构狮子{ tag_id:usize } impl狮子{ fn咆哮&自我{println!咆哮} } 狮子的动物{ fn eat&self{println!liontag={}正在吃鱼或千层面,self.tag_id} fn sleep&self{println!liontag={}在里面睡觉,self.tag_id} fn as_any&self->&dyn any{self} } fn干线{ 让动物:Vec=Vec[ 框::newCat{name:Garfield.to_string}, 框::newLion{tag_id:12} ]; //后来: 用于动物中的动物。iter{ 动物睡眠; 如果let Someanimal=animal.as\u any.downcast\u ref::{ 动物吼叫; } } }
你可以试试这样的 使用std::any::any; 特征动物{ fn吃与自我; fn睡眠与自我; fn as_any&self->&dyn any; } 结构猫{ 名称:String } impl猫{ fn喵喵&self{println!喵喵} } 猫科动物{ fn eat&self{println!cat{}正在吃鱼或千层面,self.name} fn sleep&self{println!cat{}在里面睡觉,self.name} fn as_any&self->&dyn any{self} } 结构狮子{ tag_id:usize } impl狮子{ fn咆哮&自我{println!咆哮} } 狮子的动物{ fn eat&self{println!liontag={}正在吃鱼或千层面,self.tag_id} fn sleep&self{println!liontag={}在里面睡觉,self.tag_id} fn as_any&self->&dyn any{self} } fn干线{ 让动物:Vec=Vec[ 框::newCat{name:Garfield.to_string}, 框::newLion{tag_id:12} ]; //后来: 用于动物中的动物。iter{ 动物睡眠; 如果let Someanimal=animal.as\u any.downcast\u ref::{ 动物吼叫; } } }
这可能会有帮助:这可能会有帮助:我想我知道你在做什么,我想它回答了我的问题,但代码没有按原样编译,游乐场链接又是我的了。@JustinBennett哦,对不起,我以为它是自动保存的。我会更新的link@JustinBennett我现在修复了链接,非常感谢-这绝对是解决我问题的一个子集。如果我发现“子类型”的单个任务是不连续的,即Cat还有单独的方法“运行”、“后退”和“跳跃”,而Lion有“游泳”、“行走”和“成为国王”,我该怎么办?@Justin如果它们有那么大的不同,那么为什么要将它们填充到同一个向量中?任何给定的设计都有可能出现不足的情况。作为一名设计师,你的任务是决定哪些属性与你真正要解决的问题相关,并选择一个具有这些属性的设计。我想我知道你在做什么,我想它回答了我的问题,但代码没有按原样编译,游乐场链接又是我的。@JustinBennett哦,对不起,我以为它是自动保存的。我会更新的link@JustinBennett我现在修复了链接,非常感谢-这绝对是解决我问题的一个子集。如果我发现“子类型”的单个任务是不连续的,即Cat还有单独的方法“运行”、“后退”和“跳跃”,而Lion有“游泳”、“行走”和“成为国王”,我该怎么办?@Justin如果它们有那么大的不同,那么为什么要将它们填充到同一个向量中?任何给定的设计都有可能出现不足的情况。作为设计师,你的任务是 确定哪些属性与您真正要解决的问题相关,然后选择具有这些属性的设计。
for animal in animals {
animal.sleep();
if let Some(roaring) = animal.as_roaring() {
roaring.roar();
}
}