我正在寻找一种方法,它可以生成一个Vec
并返回一个元素,而不需要像remove
和swap_remove
那样恢复Vec
的不变量:
fn take<T>(vec: Vec<T>, index: usize) -> Option<T>
然而,我找不到这样的方法.我错过什么了吗?这真的不安全还是不可能?
我正在寻找一种方法,它可以生成一个Vec
并返回一个元素,而不需要像remove
和swap_remove
那样恢复Vec
的不变量:
fn take<T>(vec: Vec<T>, index: usize) -> Option<T>
然而,我找不到这样的方法.我错过什么了吗?这真的不安全还是不可能?
你可以这样写你的函数:
fn take<T>(mut vec: Vec<T>, index: usize) -> Option<T> {
if vec.get(index).is_none() {
None
} else {
Some(vec.swap_remove(index))
}
}
这里的代码see(get
和swap_remove
)保证为O(1).
However,有点隐藏,vec
在函数末尾被删除,这个删除操作可能不是O(1),而是O(n)(其中n是vec.len()
).如果T
实现Drop
,那么对于仍然在向量内的每个元素调用drop()
,这意味着丢弃向量保证为O(n).如果T
没有实现Drop
,那么Vec
只需要释放内存.dealloc
操作的时间复杂度取决于分配器,并且没有指定,因此我们不能假设它是O(1).
提到另一个使用迭代器的解决方案:
fn take<T>(vec: Vec<T>, index: usize) -> Option<T> {
vec.into_iter().nth(index)
}
我正要写这封信:
虽然
Iterator::nth()
通常是linear time运算,但向量上的迭代器会覆盖此方法,使其成为O(1)运算.
但后来我注意到,这只适用于迭代切片的迭代器.上面代码中使用的std::vec::IntoIter
迭代器不会覆盖nth()
.已经try 了here次,但似乎没有那么容易.
所以,到目前为止,上面的迭代器解决方案是一个O(n)操作!更不用说如上所述,放下向量所需的时间了.