gpt4 book ai didi

rust - 在没有克隆或复制的情况下初始化盒装切片

转载 作者:行者123 更新时间:2023-11-29 08:12:44 30 4
gpt4 key购买 nike

我正在尝试初始化一个装箱的 None 值切片,这样底层类型 T 就不需要实现 Clone复制。这里有一些理想的解决方案:

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 实现需要T: Cloneby_arr 实现需要T: Copy。我已经尝试了更多的方法:

fn by_vec2<T>() -> Box<[Option<T>]> {
let v = &mut Vec::with_capacity(5);
for i in 0..v.len() {
v[i] = None;
}
v.into_boxed_slice() // Doesn't work: cannot move out of borrowed content
}

fn by_iter<T>() -> Box<[Option<T>]> {
(0..5).map(|_| None).collect::<Vec<Option<T>>>().into_boxed_slice()
}

by_vec2 没有通过编译器(我不确定我明白为什么),但是 by_iter 可以。我担心 collect 的性能——它是否需要在迭代时调整它正在收集的向量的大小,或者它是否可以分配正确大小的向量开始?

也许我做错了——我是 Rust 的新手,所以任何提示都将不胜感激!

最佳答案

让我们从 by_vec2 开始。您正在使用 &mutVec 的引用。你不应该这样做,直接使用 Vec 并使 v 绑定(bind)可变。

然后您将迭代容量为 5 且长度为 0 的 Vec 的长度。这意味着您的循环永远不会执行。您想要的是迭代 0..v.cap()

由于您的 v 的长度仍然为 0,因此在循环中访问 v[i] 将在运行时出现 panic。你真正想要的是 v.push(None)。这通常会导致重新分配,但在您的情况下,您已经分配了 Vec::with_capacity,因此推送 5 次将不会分配。

这一次我们没有引用 Vec,所以 into_boxed_slice 将真正起作用。

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()
}

您的 by_iter 函数实际上只分配一次。 0..5 创建的 Range 迭代器知道它恰好有 5 个元素长。所以 collect 实际上会检查该长度并只分配一次。

关于rust - 在没有克隆或复制的情况下初始化盒装切片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34284191/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com