为何向容量为1的Vec中push3个元素却未报错?
为什么Rust中Vec指定容量为1后还能多次push元素?
问题描述
我在Windows 10上使用Rust v1.26.0(a77568041 2018-05-07)编写了以下代码:
#[derive(Debug)] enum StackType { Int(i64), Float(f64), Word(String), } fn main() { let mut stack: Vec<StackType> = Vec::with_capacity(1); stack.push(StackType::Int(5)); stack.push(StackType::Float(5_f64)); stack.push(StackType::Word(String::from("ABC"))); println!("{:?}", stack); }
我原本以为这段代码会报错,因为我给Vec指定的初始容量是1,但却执行了3次push操作。然而程序正常运行并输出:
[Int(5), Float(5.0), Word("ABC")]
想请教这一现象的原因是什么?
解答
其实你是混淆了Vec的**容量(capacity)和长度(length)**这两个核心概念:
Vec::with_capacity(n)的作用只是提前分配一块能装下n个元素的内存空间,这么做是为了减少后续push操作时的内存分配次数,提升程序性能——它完全不会限制Vec能存储的最大元素数量。- 你可以把
Vec想象成一个带自动扩容功能的容器:长度是当前里面实际装了多少元素,容量是这个容器当前的“额定装载量”。当你往里面塞元素,长度快要超过容量的时候,Vec会自动申请一块更大的内存空间(通常是把现有容量翻倍),把原来的元素复制/移动过去,然后再添加新元素。
你可以给代码加几行打印,直观看看这个扩容过程:
fn main() { let mut stack: Vec<StackType> = Vec::with_capacity(1); println!("初始容量: {}, 当前长度: {}", stack.capacity(), stack.len()); // 初始容量: 1, 当前长度: 0 stack.push(StackType::Int(5)); println!("第一次push后: 容量={}, 长度={}", stack.capacity(), stack.len()); // 容量=1, 长度=1 stack.push(StackType::Float(5_f64)); println!("第二次push后: 容量={}, 长度={}", stack.capacity(), stack.len()); // 容量=2, 长度=2(自动扩容了) stack.push(StackType::Word(String::from("ABC"))); println!("第三次push后: 容量={}, 长度={}", stack.capacity(), stack.len()); // 容量=4, 长度=3(再次扩容) println!("{:?}", stack); }
如果真的需要限制Vec的最大元素数,那得自己编写逻辑控制(比如每次push前检查当前长度,超过阈值就返回错误),Rust标准库的Vec本身并没有提供这种限制功能哦。
内容的提问来源于stack exchange,提问作者Ashniu123
相关产品推荐
相关产品推荐

