插入和移除(Insert and Remove)

切片 未(not) 提供的东西是insertremove,所以接下来做.

插入需要将目标索引处的所有元素向右移动(shift)一个.要做到这一点,我们需要使用ptr::copy,这是C的memmove我们的版本.这会将一些内存从一个位置复制到另一个位置,正确处理源和目标重叠的情况(这肯定会发生在这里).

如果我们在索引i处插入,我们希望使用旧len将[i .. len]移动到[i + 1 .. len+1].

  1. pub fn insert(&mut self, index: usize, elem: T) {
  2. // Note: `<=` because it's valid to insert after everything
  3. // which would be equivalent to push.
  4. assert!(index <= self.len, "index out of bounds");
  5. if self.cap == self.len { self.grow(); }
  6. unsafe {
  7. // ptr::copy(src, dest, len): "copy from src to dest len elems"
  8. ptr::copy(self.ptr.as_ptr().add(index),
  9. self.ptr.as_ptr().add(index + 1),
  10. self.len - index);
  11. ptr::write(self.ptr.as_ptr().add(index), elem);
  12. self.len += 1;
  13. }
  14. }

移除行为以相反的方式.我们需要使用 新的(new) len将所有元素从[i+1 .. len+1]移动到[i .. len].

  1. pub fn remove(&mut self, index: usize) -> T {
  2. // Note: `<` because it's *not* valid to remove after everything
  3. assert!(index < self.len, "index out of bounds");
  4. unsafe {
  5. self.len -= 1;
  6. let result = ptr::read(self.ptr.as_ptr().offset(index as isize));
  7. ptr::copy(self.ptr.as_ptr().add(index + 1),
  8. self.ptr.as_ptr().add(index),
  9. self.len - index);
  10. result
  11. }
  12. }