Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 是否允许多态变量?_Rust - Fatal编程技术网

Rust 是否允许多态变量?

Rust 是否允许多态变量?,rust,Rust,我有各种各样的结构,它们都实现了相同的特性。我想在某些条件下进行分支,在运行时决定实例化哪些结构。然后,不管我遵循哪个分支,我都希望从该特性调用方法 这在铁锈中可能吗?我希望实现以下目标(未编译): 是的,但不是那么容易。你在那里写的是,animal应该是Barks类型的变量,但是Barks是一种特性;接口的描述。性状没有静态定义的大小,因为任何大小的类型都可能出现并且impl-Barks。编译器不知道把animal做成多大 您需要做的是添加一层间接寻址。在这种情况下,您可以使用Box,但也可以

我有各种各样的结构,它们都实现了相同的特性。我想在某些条件下进行分支,在运行时决定实例化哪些结构。然后,不管我遵循哪个分支,我都希望从该特性调用方法

这在铁锈中可能吗?我希望实现以下目标(未编译):


是的,但不是那么容易。你在那里写的是,
animal
应该是
Barks
类型的变量,但是
Barks
是一种特性;接口的描述。性状没有静态定义的大小,因为任何大小的类型都可能出现并且
impl-Barks
。编译器不知道把
animal
做成多大

您需要做的是添加一层间接寻址。在这种情况下,您可以使用
Box
,但也可以使用
Rc
或普通引用:

fn main(){
让动物:盒子;
如果1==2{
动物=盒子::新的(狗);
}否则{
动物=盒子::新的(狼);
}
动物。树皮();
}
在这里,我在堆上分配
,然后将其放入
。这有点像把对象投射到C++或java之类的接口中,或者在C++中把<代码>狗*<代码>转换成<代码> BARK**/COD>。 另一种完全不同的方法是枚举。您可以使用
enum Animal{Dog,Wolf}
,然后定义
impl Animal{fn bark(&self){…}
。这取决于你是否需要一套完全开放的动物和/或多种特征


最后,请注意上面的“种类”。在Java/C#/C++中,有许多东西无法正常工作。例如,锈病没有向下投射(你不能从
Box
返回到
Box
,也不能从一种特征到另一种特征)。此外,这仅在特征是“对象安全”的情况下有效(没有泛型,没有使用
self
self
的值)。

DK有一个很好的解释,我只想附带一个例子,我们在堆栈上分配
Dog
Wolf
,避免堆分配:

fn main(){
让狗;
让狼来;
让动物:&dyn吠叫=如果1==2{
狗=狗;
&狗
}否则{
狼=狼;
&狼
};
动物。树皮();
}
这有点难看,但是引用实现了与
相同的间接寻址,开销稍微小一些

另见:


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

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

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
中,我们只使用一个堆栈分配变量,其中包含一个自定义枚举实例。

谢谢!你提到我可以使用普通的参考资料。这是怎么回事?请参阅我的答案以获得简单的参考。我认为
candige
将是enum的更好名称。
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();
}