Vec
Vector
与我们拥有 &

和我们之前接触到的Vec
具有动态的添加和删除元素的能力,并且能够以O(1)
的效率进行随机访问。同时,对其尾部进行O(1)
的。同时,有一个非常重要的特性(虽然我们编程的时候大部分都不会考量它)就是,
另外的就是,Vec<T>
中的泛型T
必须是Sized
的,也就是说必须在编译的时候就知道存一个内容项需要多少内存。对于那些在编译时候未知大小的项(函数类型等Box
将其包裹,当成一个指针。
Vec 声明
声明向量有两种主要方法。一种类似于使用
fn main() {
let name1 = String::from("Windy");
let name2 = String::from("Gomesy");
let mut my_vec = Vec::new();
// If we run the program now, the compiler will give an error.
// It doesn't know the type of vec.
my_vec.push(name1); // Now it knows: it's Vec<String>
my_vec.push(name2);
}
或者,您可以只声明类型。
fn main() {
let mut my_vec: Vec<String> = Vec::new(); // The compiler knows the type
// so there is no error.
}
您可以看到向量中的项目必须具有相同的类型。创建向量的另一种简单方法是使用
fn main() {
let mut my_vec = vec![8, 10, 10];
}
类型是 Vec<i32>
。您称它为Vec<String>
是字符串Vec<Vec<String>>
是字符串
因为FromIterator
这个
let v: Vec<_> = (1..5).collect();
空间分配
因为
fn main() {
let mut num_vec = Vec::new();
num_vec.push('a'); // add one character
println!("{}", num_vec.capacity()); // prints 1
num_vec.push('a'); // add one more
println!("{}", num_vec.capacity()); // prints 2
num_vec.push('a'); // add one more
println!("{}", num_vec.capacity()); // prints 4. It has three elements, but capacity is 4
num_vec.push('a'); // add one more
num_vec.push('a'); // add one more // Now we have 5 elements
println!("{}", num_vec.capacity()); // Now capacity is 8
}
因此,此向量具有三个重新分配:
fn main() {
let mut num_vec = Vec::with_capacity(8); // Give it capacity 8
num_vec.push('a'); // add one character
println!("{}", num_vec.capacity()); // prints 8
num_vec.push('a'); // add one more
println!("{}", num_vec.capacity()); // prints 8
num_vec.push('a'); // add one more
println!("{}", num_vec.capacity()); // prints 8.
num_vec.push('a'); // add one more
num_vec.push('a'); // add one more // Now we have 5 elements
println!("{}", num_vec.capacity()); // Still 8
}
此向量具有Vec::with_capacity()
使其更快。您还记得可以使用Vec <_>
。
fn main() {
let my_vec: Vec<u8> = [1, 2, 3].into();
let my_vec2: Vec<_> = [9, 0, 10].into(); // Vec<_> means "choose the Vec type for me"
// Rust will choose Vec<i32>
}
访问与修改
随机访问
就像数组一样,因为Index
和IndexMut
提供了随机访问的能力,我们通过[index]
来对其进行访问,当然,既然存在随机访问就会出现越界的问题。而在for
循环中,不然我们不推荐通过下标访问。
以下是例子:
let a = vec![1, 2, 3];
assert_eq!(a[1usize], 2);
那么,.get(n: usize)
(.get_mut(n: usize)
)函数。
对于一个数组,这个函数返回一个Option<&T>
Option<&mut T>
let v =vec![1, 2, 3];
assert_eq!(v.get(1), Some(&2));
assert_eq!(v.get(3), None);
迭代器
对于一个可变数组,
let v = vec![1, 2, 3];
for i in &v { .. } // 获得引用
for i in &mut v { .. } // 获得可变引用
for i in v { .. } // 获得所有权,注意此时 Vec 的属主将会被转移!!
但是,这么写很容易出现多层for
循环嵌套,因此,Vec
提供了一个into_iter()
方法,能显式地将自己转换成一个迭代器。然而迭代器怎么用呢?我们下一章将会详细说明。
切片
fn main() {
let vec_of_ten = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Everything is the same except we added vec!
let three_to_five = &vec_of_ten[2..5];
let start_at_two = &vec_of_ten[1..];
let end_at_five = &vec_of_ten[..5];
let everything = &vec_of_ten[..];
println!("Three to five: {:?},
start at two: {:?}
end at five: {:?}
everything: {:?}", three_to_five, start_at_two, end_at_five, everything);
}