我希望有一个Vec::insert_slice(index, slice)方法——字符串(String::insert_str())的解决方案确实存在.

我知道大约Vec::insert()个元素,但一次只插入一个元素,而不是一个片段.或者,当带前缀的切片是Vec时,可以将其附加,但这并不是泛化.惯用的解决方案可能使用Vec::splice(),但像示例中那样使用迭代器让我摸不着头脑.

第二,预编的整个概念似乎已经从docs人中消失了.一句话也没有提到.如果您能就原因发表 comments ,我将不胜感激.请注意,像Vec::swap_remove()这样相对模糊的方法确实存在.

我的典型用例由索引字节字符串组成.

推荐答案

String::insert_str利用了字符串本质上是Vec<u8>这一事实.reallocates the underlying buffer, moves all the initial bytes to the end, then adds the new bytes to the beginning美元.

这通常不安全,不能直接添加到Vec,因为在复制过程中,Vec不再处于有效状态——数据中存在"漏洞".

这对于String来说并不重要,因为数据是u8u8不实现Drop.对于Vec中任意的T,没有这样的保证,但是如果你非常小心地跟踪你的状态并正确地清理,你可以做同样的事情——这就是splice所做的!

预告的整个概念似乎已经被驱除

我想这是因为从性能的Angular 来看,预选Vec分是个糟糕的主意.如果你需要这么做,天真的情况是直截了当的:

fn prepend<T>(v: Vec<T>, s: &[T]) -> Vec<T>
where
    T: Clone,
{
    let mut tmp: Vec<_> = s.to_owned();
    tmp.extend(v);
    tmp
}

这有一个更高的内存使用率,因为我们需要有足够的空间为两份v.

splice方法接受一个新值的迭代器和一系列要替换的值.在这种情况下,我们不想替换任何内容,所以我们给出了一个空的索引范围来插入.我们还需要将切片转换为适当类型的迭代器:

let s = &[1, 2, 3];
let mut v = vec![4, 5];

v.splice(0..0, s.iter().cloned());

splice's implementation is non-trivial,但它能有效地进行我们需要的追踪.删除一个值块后,它将为新值删除该内存块.它还会移动向量的尾部(可能会移动几次,具体取决于输入迭代器).SliceDrop实现确保事物始终处于有效状态.


我更惊讶的是,VecDeque不支持它,因为它的设计目的是更有效地修改数据的开头和结尾.

Rust相关问答推荐

如何在不安全的代码中初始化枚举 struct

rust 蚀将动力特性浇到混凝土 struct 上是行不通的

默认特征实现中的生命周期问题

取得本地对象字段的所有权

Tokio_Postgres行上未显示退回特性的生存期,且生命周期 不够长

`Pin`有没有不涉及不安全代码的目的?

如何实现Serde::Ser::Error的调试

习语选项<;T>;到选项<;U>;当T->;U用From定义

不同类型泛型的映射

如何对一个特征的两个实现进行单元测试?

为什么在 Allocator API 中 allocate() 使用 `[u8]` 而 deallocate 使用 `u8` ?

使用 pyo3 将 Rust 转换为 Python 自定义类型

在 Rust 中,为什么 10 个字符的字符串的 size_of_val() 返回 24 个字节?

write_buffer 不写入缓冲区而是输出零 WGPU

为什么这个闭包没有实现Fn?

在Rust中实现Trie数据 struct 的更好方式

Rust编译器通过哪些规则来确保锁被释放?

将原始可变指针传递给 C FFI 后出现意外值

当 `T` 没有实现 `Debug` 时替代 `unwrap()`

如何重写这个通用参数?