基本数据类型和所有权本来就迷迷糊糊,现在在循环也要时刻谨记所有权。
无论什么情况,都要时刻谨记所有权 ----鲁迅。
for循环所有权
使用方法 |
等价使用的方法 |
所有权 |
for item in collection{
//pass
}
|
for item in IntoIterator::into_iter(collection) {
//pass
}
|
collection所有权给了for循环,后面不能使用了 |
for item in &collection{
//pass
}
|
for item in collection.iter() {
//pass
}
|
collection所有权借给了for循环,collection后面依旧能够使用 |
for item in &mut collection{
//pass
}
|
for item in collection.iter_mut() {
//pass
}
|
collection可变借用,collection后面依旧能够使用(但是变了) |
两种循环方式优劣对比
以下代码,使用了两种循环方式:
// 第一种
let collection = [1, 2, 3, 4, 5];
for i in 0..collection.len() {
let item = collection[i];
// ...
}
// 第二种
for item in collection {
}
第一种方式是循环索引,然后通过索引下标去访问集合,第二种方式是直接循环集合中的元素,优劣如下:
- 性能:第一种使用方式中 collection[index] 的索引访问,会因为边界检查(Bounds Checking)导致运行时的性能损耗 —— Rust 会检查并确认 index 是否落在集合内,但是第二种直接迭代的方式就不会触发这种检查,因为编译器会在编译时就完成分析并证明这种访问是合法的
- 安全:第一种方式里对 collection 的索引访问是非连续的,存在一定可能性在两次访问之间,collection 发生了变化,导致脏数据产生。而第二种直接迭代的方式是连续访问,因此不存在这种风险( 由于所有权限制,在访问过程中,数据并不会发生变化)。
由于 for 循环无需任何条件限制,也不需要通过索引来访问,因此是最安全也是最常用的。