我想在Rust中创建一个非二叉树结构.这是一个尝试
struct TreeNode<T> {
tag : T,
father : Weak<TreeNode<T>>,
childrenlists : [Rc<TreeNode<T>>]
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不编译.
main.rs:4:1: 8:2 error: the trait `core::marker::Sized` is not implemented for the type `[alloc::rc::Rc<TreeNode<T>>]` [E0277]
main.rs:4 struct TreeNode<T> {
main.rs:5 tag : T,
main.rs:6 father : Weak<TreeNode<T>>,
main.rs:7 childrenlist : [Rc<TreeNode<T>>]
main.rs:8 }
main.rs:4:1: 8:2 note: `[alloc::rc::Rc<TreeNode<T>>]` does not have a constant size known at compile-time
main.rs:4 struct TreeNode<T> {
main.rs:5 tag : T,
main.rs:6 father : Weak<TreeNode<T>>,
main.rs:7 childrenlist : [Rc<TreeNode<T>>]
main.rs:8 }
error: aborting due to previous error
Run Code Online (Sandbox Code Playgroud)
如果我们用a替换数组,代码就会编译Vec.但是,结构是不可变的,我不需要进行过度分配Vec.
我听说有可能在编译时有一个大小未知的结构字段,只要它是唯一的.我们怎么做?
Man*_*rth 27
Rust没有可变长度(堆栈)数组的概念,您似乎试图在这里使用它.
Rust有几种不同的array-ish类型.
Vec<T>("矢量"):动态大小; 在堆上动态分配.这可能是你想要使用的.初始化它Vec::with_capacity(foo)以避免过度分配(这会创建一个具有给定容量的空向量).[T; n]("数组"):静态大小; 生活在堆栈上.你需要在编译时知道大小,所以这对你不起作用(除非我错误地分析了你的情况).[T]("切片"):未标注; 通常用于&[T].这是T对内存中某个连续s 的视图.您可以通过引用数组或向量(称为"获取数组/向量的切片"),甚至将视图转换为数组/向量的子集来获得它.未经过大小写,[T]不能直接用作变量(它可以用作unsized struct的成员),但是您可以从指针后面查看它.指的[T]是脂肪 ; 即他们有一个额外的长度字段.&[T]如果要存储对现有数组的引用,将会很有用; 但我不认为这就是你想要做的.如果您事先不知道列表的大小,您有两种选择:
&[T] 这只是对你不拥有的某些内存的引用Vec<T>这是你自己的存储空间.这里正确的是使用a Vec.为什么?因为您希望子列表(数组Rc)实际拥有TreeNode.如果您使用了a &[T],则意味着其他人将保留列表,而不是TreeNode.使用一些终身技巧,你可以编写一些有效的代码,但你必须走得很远才能取悦编译器,因为借用的引用必须至少与有效代码一样长TreeNode.
最后,你问题中的一句话表明存在误解:
但是,结构是不可变的,我不需要一个过度定位的Vec.
你混淆了可变性和所有权.当然你可以有一个不可变的Vec.看起来你想避免从堆中分配内存,但这是不可能的,正是因为你不知道子列表的大小.现在,如果你关心overallocating,您可以微调用类似方法载体存储with_capacity()和shrink_to_fit().
最后一点:如果您确实知道列表的大小,因为它在编译时是固定的,您只需要使用[T; n]where n编译时已知的.但那不一样[T].
| 归档时间: |
|
| 查看次数: |
13779 次 |
| 最近记录: |