递归类型和数组

时间:2015-01-28 22:12:06

标签: rust

好的,所以我刚开始学习一点Rust,我正在遇到一个非常简单的问题。我有这样的递归类型:

struct Tree {
    root : i32,
    children : Box<[Option<Tree> ; 100]>
}

后来,当我尝试初始化Tree

hex.rs:30:29: 30:40 error: the trait `core::marker::Copy` is not implemented for the type `Tree` [E0277]
hex.rs:30         children : Box::new([None; 100])
                                      ^~~~~~~~~~~
error: aborting due to previous error

所以,我添加了

#[derive(Copy)]
在结构定义之前

,但是我收到了这个错误:

hex.rs:8:10: 8:14 error: the trait `Copy` may not be implemented for this type; field `children` does not implement `Copy` [E0204]
hex.rs:8 #[derive(Copy)]
                  ^~~~
note: in expansion of #[derive]
hex.rs:8:1: 8:16 note: expansion site
error: aborting due to previous error

我不完全确定从哪里开始。是否有一种简单的方法来推导递归数据类型的特征?

2 个答案:

答案 0 :(得分:1)

问题在于Box不支持Copy。复制状态:

  

只需复制位即可复制的类型

但是,Box包含指向内存的指针,当您只复制指针的位时,不会复制该内存。

当你构建你的数组时,Rust只知道你要在那里放一个Option。没有办法让enum只实现一半特征。

您需要使用固定大小的阵列吗?也许这会更好:

struct Tree {
    root : i32,
    children : Vec<Tree>
}

然后,您的构造函数可以使用Vec::with_capacity

impl Tree {
    fn new(root: i32) -> Tree {
        Tree { root: root, children: Vec::with_capacity(100) }
    }
}

答案 1 :(得分:1)

我担心如果没有unsafe,您将无法使用静态数组和递归类型。原因是数组初始值设定项要求数组元素类型为Copy,因为它们使用初始元素的逐字节副本初始化所有元素,并且您的类型不能是Copy,因为它包含Box这是在Rust中允许递归类型的唯一安全方法(好吧,还有Vec和其他类似的容器,但它们也需要堆分配。)

如果你不害怕分配,你也可以使用Vec

struct Tree {
    root: i32,
    children: Vec<Tree>
}

然后初始化看起来像

Tree {
    root: 0,
    children: vec![]
}