Rust 在不克隆或复制的情况下初始化盒装切片
我正在尝试初始化一个包含Rust 在不克隆或复制的情况下初始化盒装切片,rust,Rust,我正在尝试初始化一个包含None值的盒式切片,这样底层类型T就不需要实现Clone或Copy。以下是一些理想的解决方案: fn by_vec<T>() -> Box<[Option<T>]> { vec![None; 5].into_boxed_slice() } fn by_arr<T>() -> Box<[Option<T>]> { Box::new([None; 5]) } by_vec
None
值的盒式切片,这样底层类型T
就不需要实现Clone
或Copy
。以下是一些理想的解决方案:
fn by_vec<T>() -> Box<[Option<T>]> {
vec![None; 5].into_boxed_slice()
}
fn by_arr<T>() -> Box<[Option<T>]> {
Box::new([None; 5])
}
by_vec2
无法通过编译器(我不知道为什么),但是by_iter
可以。我关心的是collect
的性能——它是否需要在迭代时调整它收集到的向量的大小,或者它是否可以首先分配正确大小的向量
也许我完全搞错了——我对生锈很陌生,所以任何提示都将不胜感激 让我们从
by\u vec2
开始。您正在将&mut
引用带到Vec
。您不应该这样做,直接使用Vec
并使v
绑定可变
然后在容量为5、长度为0的Vec
上迭代。这意味着你的循环永远不会被执行。您想要的是迭代0..v.cap()
由于v
的长度仍然为0,因此在循环中访问v[i]
将在运行时死机。你真正想要的是v.push(无)
。这通常会导致重新分配,但在您的情况下,您已经分配了Vec::with_capacity
,因此推5次不会分配
这一次,我们没有引用Vec
,因此到_boxed_切片中
将实际起作用
fn by_vec2<T>() -> Box<[Option<T>]> {
let mut v = Vec::with_capacity(5);
for _ in 0..v.capacity() {
v.push(None);
}
v.into_boxed_slice()
}
fn by_vec2()->Box{
设mut v=Vec::具有_容量(5);
对于0..v容量(){
v、 推送(无);
}
v、 放入盒装的切片()
}
您的
by\u iter
函数实际上只分配一次。由0..5
创建的范围迭代器知道正好有5个元素长。因此,collect
实际上将检查该长度并只分配一次。让我们从开始。您正在将&mut
引用带到Vec
。您不应该这样做,直接使用Vec
并使v
绑定可变
然后在容量为5、长度为0的Vec
上迭代。这意味着你的循环永远不会被执行。您想要的是迭代0..v.cap()
由于v
的长度仍然为0,因此在循环中访问v[i]
将在运行时死机。你真正想要的是v.push(无)
。这通常会导致重新分配,但在您的情况下,您已经分配了Vec::with_capacity
,因此推5次不会分配
这一次,我们没有引用Vec
,因此到_boxed_切片中
将实际起作用
fn by_vec2<T>() -> Box<[Option<T>]> {
let mut v = Vec::with_capacity(5);
for _ in 0..v.capacity() {
v.push(None);
}
v.into_boxed_slice()
}
fn by_vec2()->Box{
设mut v=Vec::具有_容量(5);
对于0..v容量(){
v、 推送(无);
}
v、 放入盒装的切片()
}
您的by\u iter
函数实际上只分配一次。由0..5
创建的范围迭代器知道正好有5个元素长。因此,collect
实际上将检查该长度并只分配一次。我认为这里最重要的是范围迭代器[…]知道它正好有5个元素长。这就是我编写这段代码的方式,尽管我会对collect
类型参数使用类型推断:(0..5).map(| | | None).collect::()。into_boxed_slice()
。我认为这里最重要的是范围迭代器[…]知道它正好有5个元素长。这就是我编写这段代码的方式,尽管我会对collect
类型参数:(0..5).map(| | | None).collect::()进行类型推断,将其转换为_boxed_slice()
。