首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从Trait1 Box<dyn Trait1 + Trait2>返回和恢复

从Trait1 Box<dyn Trait1 + Trait2>返回和恢复
EN

Stack Overflow用户
提问于 2020-02-10 20:32:42
回答 1查看 216关注 0票数 2

如果我有一个Box<dyn Trait1 + Trait2>,我可以返回一个&dyn Trait1吗?

为了给出一些背景,我试图在铁锈中实现一个(专门的)图表。这个SpecialisedGraph需要一些标准的图形算法,我希望使用可以跨几个图形类型共享的Graph特性来实现这些算法,但这段代码没有编译:

代码语言:javascript
复制
trait Node {
    //...
}

trait Graph {
    fn get_node(&self, key: &str) -> Option<&dyn Node>;
}

trait SpecialisedNode {
    //...
}

trait SpecialisedGraphNode: SpecialisedNode + Node {}

struct SpecialisedGraph {
    nodes: HashMap<String, Box<dyn SpecialisedGraphNode>>
}

impl Graph for SpecialisedGraph {
    fn get_node(&self, key: &str) -> Option<&dyn Node> {
        match self.nodes.get(key) {
            Some(node) => Some(&(**node)),
            None => None
        }
    }
}

有错误:

代码语言:javascript
复制
error[E0308]: mismatched types
  --> src\main.rs:25:32
   |
25 |             Some(node) => Some(&(**node)),
   |                                ^^^^^^^^^ expected trait `Node`, found trait `SpecialisedGraphNode`
   |
   = note: expected reference `&dyn Node`
              found reference `&dyn SpecialisedGraphNode`

编辑:我编辑了这个问题以反映评论。

EDIT2:使用Shepmaster提供的链接Why doesn't Rust support trait object upcasting?找到了我问题的答案。

下面更新的代码现在开始工作了,谢谢大家。

代码语言:javascript
复制
trait AsNode {
    fn as_node(&self) -> &dyn Node;
}

trait Node : AsNode {
    //...
}

impl<T: Node> AsNode for T {
    fn as_node(&self) -> &dyn Node {
        self
    }
}

trait Graph {
    fn get_node(&self, key: &str) -> Option<&dyn Node>;
}

trait SpecialisedNode : Node {
    //...
}

struct SpecialisedGraph {
    nodes: HashMap<String, Box<dyn SpecialisedNode>>
}

impl Graph for SpecialisedGraph {
    fn get_node(&self, key: &str) -> Option<&dyn Node> {
        match self.nodes.get(key) {
            Some(node) => Some(node.as_node()),
            None => None
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-10 20:39:16

不能,HashMap<String, Box<dyn SpecialisedGraphNode>不是HashMap<String, Box<dyn Node>,所以不能形成那种类型的引用。如果使用不安全的代码执行此操作,则会调用未定义的行为,因为这些框没有相同的数据。

我还认为您的感觉是错误的--至少Java、C++和C# (可以说是最常见的静态类型OO语言)也不允许您这样做。(C#允许您对接口执行IReadOnlyDictionary和协变泛型参数的类似操作。但不适用于混凝土类型。)

您可能需要重新考虑您的Graph特性。它真的必须以散列映射的形式提供对节点的访问吗?也许它可以简单地提供一个函数来查找一个节点,并将其作为一个&dyn Node返回。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60157976

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档