有没有办法将变量分配给不同的特征实现?

Is there a way to reassign a variable to a different trait implemetation?

我可以有一个变量可以分配给实现相同特征的 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() 构造函数更改为 return impl Node

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

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

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

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

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

需要装箱,因为此时尺寸未知。

你可以这样创建一个值:

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

注:

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