【发布时间】:2016-04-27 15:06:01
【问题描述】:
我遇到了与 Rust 的所有权规则和特征对象向下转换的冲突。这是一个示例:
use std::any::Any;
trait Node{
fn gen(&self) -> Box<Node>;
}
struct TextNode;
impl Node for TextNode{
fn gen(&self) -> Box<Node>{
Box::new(TextNode)
}
}
fn main(){
let mut v: Vec<TextNode> = Vec::new();
let node = TextNode.gen();
let foo = &node as &Any;
match foo.downcast_ref::<TextNode>(){
Some(n) => {
v.push(*n);
},
None => ()
};
}
TextNode::gen 方法必须返回 Box<Node> 而不是 Box<TextNode>,所以我必须将其向下转换为 Box<TextNode>。
Any::downcast_ref 的返回值是Option<&T>,所以我无法获取向下转换结果的所有权并将其推送到v。
====编辑=====
由于我英语不好,所以我的问题很模糊。
I am implementing(复制可能更精确)Go 标准库中的模板解析器。
我真正需要的是一个向量,Vec<Box<Node>> 或Vec<Box<Any>>,它可以包含TextNode、NumberNode、ActionNode,任何类型的节点都可以实现Node 的特征.
每个节点类型都需要实现copy方法,返回Box<Any>,然后向下转换为具体类型即可。但是要复制Vec<Box<Any>>,因为你不知道每个元素的具体类型,你必须一一检查,效率很低。
如果复制方法返回Box<Node>,那么复制Vec<Box<Node>>很简单。但似乎没有办法从 trait 对象中获取具体类型。
【问题讨论】:
-
能否请您在您尝试移植的 Go 中链接原件?我不熟悉它
-
嗨,Go代码在github.com/golang/go/blob/master/src/text/template/parse/…,结构
ListNode有一个字段Nodes [] Node,它可以包含所有实现interface Node的节点结构,你可以得到具体类型带有类型断言blog.denevell.org/golang-interface-type-assertions-switch.html, -
在 Rust 中,我将采用我在答案中给出的
enum方法作为起点。 Go does not really have enums,所以他们插入一个NodeType来判断一个节点是PipeNode还是ActionNode。在 Rust 中你不需要它。也去does not have generics and uses interfaces and type switches for most of their use cases。我会说尝试使用 enum 并在遇到问题时回来提问
标签: rust