I've met a conflict with Rust's ownership rules and a trait object downcast. This is a sample:
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 => ()
};
}
The TextNode::gen
method has to return Box<Node>
instead of Box<TextNode>
, so I have to downcast it to Box<TextNode>
.
Any::downcast_ref
's return value is Option<&T>
, so I can't take ownership of the downcast result and push it to v
.
====edit=====
As I am not good at English, my question is vague.
I am implementing (copying may be more precise) the template parser in Go standard library.
What I really need is a vector, Vec<Box<Node>>
or Vec<Box<Any>>
, which can contain TextNode
, NumberNode
, ActionNode
, any type of node that implements the trait Node
can be pushed into it.
Every node type needs to implement the copy
method, return Box<Any>
, and then downcasting to the concrete type is OK. But to copy Vec<Box<Any>>
, as you don't know the concrete type of every element, you have to check one by one, that is really inefficient.
If the copy method returns Box<Node>
, then copying Vec<Box<Node>>
is simple. But it seems that there is no way to get the concrete type from trait object.