为什么 vec![Vec::with_capacity(n)] 为子向量创建 0 容量?

Tim*_*Tim 6 allocation vector rust

给定以下代码,为什么capacity每个向量的 是 0 而不是chunk_size

#[test]
fn test() {
    let chunk_size = 1024;
    let data: Vec<Vec<u8>> = vec![Vec::with_capacity(chunk_size); 2];

    assert_eq!(data[0].capacity(), chunk_size);
    assert_eq!(data[1].capacity(), chunk_size);
}
Run Code Online (Sandbox Code Playgroud)

游乐场链接:https://play.rust-lang.org/?version= stable&mode=debug&edition=2021&gist=0c40515b164044621c369adef1090c6e

Cha*_*man 8

并非全部都是 0,第二个是 1024:

fn main() {
    let chunk_size = 1024;
    let data: Vec<Vec<u8>> = vec![Vec::with_capacity(chunk_size); 2];

    dbg!(data[0].capacity(), data[1].capacity());
}
Run Code Online (Sandbox Code Playgroud)

游乐场

如果我们增加外部向量的大小,我们可以看到它始终是最后一个元素,即 1024,而所有其他元素均为 0。

这是为什么?

那是因为vec![]宏用于Clone填充元素。为了不克隆超出需要的元素,它会克隆除最后一个元素之外的所有元素,并重新使用为最后一个元素提供的元素(因为它需要它来供所有其他元素克隆)。

克隆一个Vec不考虑容量。它只分配足够的元素来保存长度。如果你考虑到容量并不总是有意的,那么这个决定是有道理的:很多时候,大多数时候,它只是在Vec推动容量增长时所剩下的。那么,当我们有一个全新的开始时,为什么要分配比需要的更多的钱呢?