首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么for循环绑定上的‘`ref’与正在循环的变量上的‘& mut`’不同?

为什么for循环绑定上的‘`ref’与正在循环的变量上的‘& mut`’不同?
EN

Stack Overflow用户
提问于 2018-12-05 11:43:57
回答 1查看 712关注 0票数 2

生锈中,它说:

在赋值左边的ref借款相当于右边的&借款。

我认为这两个for循环是等价的:

成功编译:

代码语言:javascript
复制
let mut v2 = vec![1, 2, 3];
for i in &mut v2 {
    *i = *i + 1;
}
println!("{:?}", v2);

不编译:

代码语言:javascript
复制
let mut v1 = vec![1, 2, 3];
for ref mut i in v1 {
    *i = *i + 1;
}
println!("{:?}", v1);

v似乎被感动了:

代码语言:javascript
复制
error[E0382]: use of moved value: `v1`
 --> src/main.rs:6:22
  |
3 |     for ref mut i in v1 {
  |                      -- value moved here
...
6 |     println!("{:?}", v1);
  |                      ^^ value used here after move
  |
  = note: move occurs because `v1` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-05 11:56:45

你从这本书中引用的是一条关于正常作业的规则,比如let的那些。例如:

代码语言:javascript
复制
let x = &42;
let ref x = 42;

但是,for循环中的名称绑定有一点不同:

  • 要循环的值被转换为迭代器(<v1 as IntoIterator>::into_iter()),让它调用该it的结果。
  • 然后重复调用it.next()
    • 如果它返回Some(_),那么它的值将绑定到您的变量。就像你写了let Some(ref mut i) = it.next()let Some(mut i) = it.next()一样。这里是ref重要的地方。
    • 如果它返回None,则循环结束。

因此,在for循环的情况下,ref&不是等价的。

当您在循环的右侧使用&时,它不会直接更改变量的绑定;您只需更改迭代对象的类型。然后,所有这些都归结为IntoIteratorVec<_>实现和&Vec<_>的实现。

  • 如果迭代Vec<T>,它将获得向量的所有权,迭代将返回值本身。因此,for i in v1使用向量,而i具有包含值的类型( T )。
  • 如果迭代&Vec<T>,它借用向量,迭代返回指向包含的值的指针( &T ),因此在for i in &v1中,i类型实际上是指向值的指针。for i in v1.iter()也能达到同样的效果。
  • 如果您迭代&mut Vec<T>,就像前面的迭代一样,但是是可变的,所以迭代返回&mut T类型的值。

结论是,在ref循环中使用for可能不是那么有用。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53631539

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档