有没有办法将变量重新分配给其他特征实现?

时间:2019-07-25 14:00:37

标签: rust traits

我可以有一个变量,可以分配给实现相同特征的2个结构吗?

简单的例子

trait Node {
    fn some_function(&self);
}
struct Edge {
    begin: bool,
}
struct Repeat {
    bar: usize,
}

impl Node for Edge {
    fn some_function(&self) { /*...*/ }
}

impl Node for Repeat {
    fn some_function(&self) { /*...*/ }
}

impl Edge {
    fn new() -> Self {
        Edge { begin: true }
    }
}

impl Repeat {
    fn new(ch: u8) -> Repeat
    {
       Repeat { bar: 100 }
    }
}

fn process_seq<'a>(bytes: &'a [u8]) -> Option<impl Node> {
    let mut node = None;
    // These both implement the same trait
    node = Some(as_node(Edge::new()));
    node = Some(as_node(Repeat::new()));
    //
    node
}

这是我到目前为止尝试过的

//一个回退到节点的函数

fn as_node<T: Node>(t: T) -> impl Node {
    t
}

error[E0308]: mismatched types
note: expected type `regexgen::Edge`
      found type `regexgen::Repeat`

//更改new()构造函数以返回impl Node

impl Edge {
    fn new() -> impl Node {
        Edge { begin: true }
    }
}

impl Repeat {
    fn new(ch: u8) -> impl Node
    {
       Repeat { bar: 100 }
    }
}

但是这给出了2个相似但不透明的类型,它们看起来可能相同,但是我知道Rust对待它们的方式有所不同。

1 个答案:

答案 0 :(得分:1)

您想要一个变量,其值可以是实现特性的一个选项。

您可以将变量定义为类型Option<Box<dyn Node>>

需要装箱,因为此时大小未知。

您可以创建一个像这样的值:

let mut node: Option<Box<dyn Node>> = Some(Box::new(Edge::new()));

注意:

正如dyn关键字明确指出的那样,动态找到要调用的函数,这会影响性能。堆分配的盒子内容也可能对您的性能造成负担(很小)。当然,影响通常可以忽略不计。

相关问题