Rust 中用于图形的异构容器

Heterogenous containers in Rust for a graph

我是一名学习 Rust 的 C++ 程序员,我的主要用例之一是基于图形的计算引擎。在我的图表中,我存储了一个同类类型,然后我从中派生了一个更具体的类型,例如在 C++ 中

class BaseNode {
  public:
    BaseNode(std::vector<std::shared_ptr<BaseNode>>& parents);
    virtual ~BaseNode() = default;

    virtual void update(); 
    const std::vector<std::shared_ptr<BaseNode>>& parents() const;
    ...
};

template<typename T>
class TypedNode<T> : public BaseNode {
  public:
    const T& value() const { return value_; }

    ...
  private:
    T value_;
}

思路是遍历图,在每个节点上调用update()。该节点知道其每个父节点 "true type" 是什么,因此在其 update() 中可以执行类似 static_cast<TypedNode<DataBlob>>(parents()[0]).

的操作

如何在 Rust 中实现这样的功能?

我想过这样的设计:

trait BaseNode {
    fn parents(&self) -> &Vec<dyn BaseNode>;
}

trait TypedNode<T>: BaseNode {
    fn value(&self) -> &T;
}

但我读到我无法将 "trait object" 从 BaseNode 转换为 TypedNode<T>。 (或者我可以使用 unsafe 以某种方式做到这一点吗?)。我认为的另一种选择是有一个结构将数据存储在 Any 中,然后对其进行转换,但这会产生一些运行时成本吗?

如果所有节点的父节点都具有相同的类型,那么您可以使用该方法:

trait BaseNode {
    type Parent: BaseNode;
    fn parents(&self) -> &[Self::Parent];
}

trait TypedNode<P: BaseNode>: BaseNode<Parent = P> {
    type ValueType;
   fn value(&self) -> &Self::ValueType;
}

Rust playground

我不确定我是否理解你的问题。如果它对您不起作用,请告诉我。