Copyright © 2022-2025 aizws.net · 网站版本: v1.2.6·内部版本: v1.25.2·
页面加载耗时 0.00 毫秒·物理内存 151.1MB ·虚拟内存 1437.8MB
欢迎来到 AI 中文社区(简称 AI 中文社),这里是学习交流 AI 人工智能技术的中文社区。 为了更好的体验,本站推荐使用 Chrome 浏览器。
slice并没有提供插入和删除功能,接下来我们就实现它们。
插入需要把目标位置后的所有元素都向右移动1。这里我们需要用到ptr::copy,它就是C中的memmove的Rust版。它把一块内存从一个地方拷贝到另一个地方,而且可以正确处理源和目标内存区域有重叠的情况(也正是我们这里遇到的情况)。
如果我们在i的位置插入,我们需要把[i .. len]移动到[i+1 .. len+1],len指的是插入前的值。
pub fn insert(&mut self, index: usize, elem: T) {
// 注意:<=是因为我们可以把值插到所有元素的后面
// 这种情况等同于push
assert!(index <= self.len, "index out of bounds");
if self.cap == self.len { self.grow(); }
unsafe {
if index < self.len {
// ptr::copy(src, dest, len): "从src拷贝len个元素到dest"
ptr::copy(self.ptr.offset(index as isize),
self.ptr.offset(index as isize + 1),
self.len - index);
}
ptr::write(self.ptr.offset(index as isize), elem);
self.len += 1;
}
}
删除则是完全相反的行为。我们要把元素[i+1 .. len + 1]移动到[i .. len],len是删除后的值。
pub fn remove(&mut self, index: usize) -> T {
// 注意:<是因为我们不能删除所有元素之后的位置
assert!(index < self.len, "index out of bounds");
unsafe {
self.len -= 1;
let result = ptr::read(self.ptr.offset(index as isize));
ptr::copy(self.ptr.offset(index as isize + 1),
self.ptr.offset(index as isize),
self.len - index);
result
}
}
我们继续编写迭代器。iter和iter_mut其实已经写过了,感谢神奇的DeRef。但是还有两个有意思的迭代器是Vec提供的而slice没有的:into_iter和drain。IntoIter以值而不是引用的形式 ...