如何在不分配内存的情况下将 Vec 拆分为两个?

问题描述

我正在寻找类似于 slice::split_at_mut函数。让我们用签名将其命名为 split_at

pub fn split_at<T>(v: Vec<T>,mid: usize) -> (Vec<T>,Vec<T>)

这样

let v = vec![1,2,3,4];
let (first,second) = split_at(v,2);
assert_eq!(first,vec![1,2]);
assert_eq!(second,vec![3,4]);

函数不应分配内存,只需将向量一分为二。您无需担心容量,因为结果向量不会被修改

仅夜间使用的方法 Vec::into_raw_parts 看起来很有前途,但我在稳定的发布渠道上不允许使用此类方法

解决方法

您的请求,正如措辞,用 Vec 是不可能的。 Vec 表示分配的内存的唯一所有权。当 Vec 超出范围时,该内存将被释放。

如果你能做到你所要求的,那么你要么

  1. 释放一段内存两次(起始内存)
  2. 解除分配一块未分配的内存(内存中间的某处)

这两种情况都是内存不安全,这正是 Rust 旨在防止的。


您可能来自带有垃圾收集器的编程语言,这也是解决相同问题的一种方法。

bytes crate 提供了一个引用计数的类向量类型,称为 Bytes(或其他情况下的 BytesMut):

use bytes::Bytes; // 1.0.1

fn main() {
    let v = Bytes::from(vec![1,2,3,4]);
    let (first,second) = v.split_at(2);
    assert_eq!(first,vec![1,2]);
    assert_eq!(second,vec![3,4]);
}
,

不完全是我想要的,但 split_off 已经足够接近了。

let mut vec = vec![1,3];
let vec2 = vec.split_off(1);
assert_eq!(vec,[1]);
assert_eq!(vec2,[2,3]);

回答我自己的问题

pub fn split_at<T>(mut v: Vec<T>,mid: usize) -> (Vec<T>,Vec<T>) {
    let remainder = v.split_off(mid);
    (v,remainder)
}