为了账号安全,请及时绑定邮箱和手机立即绑定

是否允许多态变量?

是否允许多态变量?

Git
慕慕森 2019-10-21 15:44:45
我有各种结构都实现相同的特征。我想在某种条件下分支,在运行时确定要实例化哪些结构。然后,无论我跟随哪个分支,我都希望从该特征调用方法。在Rust中这可能吗?我希望实现类似以下的内容(无法编译):trait Barks {    fn bark(&self);}struct Dog;impl Barks for Dog {    fn bark(&self) {        println!("Yip.");    }}struct Wolf;impl Barks for Wolf {    fn bark(&self) {        println!("WOOF!");    }}fn main() {    let animal: Barks;    if 1 == 2 {        animal = Dog;    } else {        animal = Wolf;    }    animal.bark();}
查看完整描述

3 回答

?
海绵宝宝撒

TA贡献1809条经验 获得超8个赞

DK有一个很好的解释,我将举一个例子,在该例子中我们在堆栈上分配Dogor Wolf,避免堆分配:


fn main() {

    let dog;

    let wolf;

    let animal: &Barks;

    if 1 == 2 {

        dog = Dog;

        animal = &dog;

    } else {

        wolf = Wolf;

        animal = &wolf;

    }

    animal.bark();

}

这有点丑陋,但是引用实现的间接寻址与相同,而Box开销却很少。


查看完整回答
反对 回复 2019-10-21
?
拉风的咖菲猫

TA贡献1995条经验 获得超2个赞

定义自定义枚举是最有效的方法。这将允许您在堆栈上精确分配所需的空间量,即最大选项的大小,再加上1个额外的字节以跟踪存储哪个选项。与使用a Box或trait引用的解决方案不同,它还允许直接访问而无需间接级别。


不幸的是,它确实需要更多样板:


enum WolfOrDog {

    IsDog(Dog),

    IsWolf(Wolf)

}

use WolfOrDog::*;


impl Barks for WolfOrDog {

    fn bark(&self) {

        match *self {

            IsDog(ref d) => d.bark(),

            IsWolf(ref w) => w.bark()

        }

    }

}


fn main() {

    let animal: WolfOrDog;

    if 1 == 2 {

        animal = IsDog(Dog);

    } else {

        animal = IsWolf(Wolf);

    }

    animal.bark();

}

在这里,main我们只使用一个堆栈分配的变量,其中包含我们自定义枚举的一个实例。


查看完整回答
反对 回复 2019-10-21
  • 3 回答
  • 0 关注
  • 566 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信