[英]What's the difference between ref and & when assigning a variable from a reference?
这段代码有什么问题?
fn example() {
let vec = vec![1, 2, 3];
let &_y = &vec;
}
error[E0507]: cannot move out of borrowed content
--> src/lib.rs:3:15
|
3 | let &_y = &vec;
| --- ^^^^ cannot move out of borrowed content
| ||
| |data moved here
| help: consider removing the `&`: `_y`
|
note: move occurs because `_y` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
--> src/lib.rs:3:10
|
3 | let &_y = &vec;
| ^^
为什么这是正确的?
let vec = vec![1, 2, 3];
let ref _y = &vec;
模式绑定可以得到一些使用;)
为了理解编译器的作用,可以使用let _: () = ...;
特技。 通过分配type ()
的变量,可以强制编译器打印一条错误消息,为您提供为变量推断的类型。
在第一个例子中:
let vec = vec![1, 2, 3];
let &y = &vec;
let _: () = y;
我们得到:
error[E0308]: mismatched types --> src/lib.rs:4:13 | 4 | let _: () = y; | ^ expected (), found struct `std::vec::Vec` | = note: expected type `()` found type `std::vec::Vec<{integer}>`
y
的类型是Vec<i32>
。
这意味着你是:
vec
成为临时的 vec
转移到y
,这是禁止的,因为vec
已经被借用了。 等效的正确代码是:
let vec = vec![1, 2, 3];
let y = vec;
在第二个例子中:
let vec = vec![1, 2, 3];
let ref y = &vec;
let _: () = y;
我们得到:
error[E0308]: mismatched types --> src/lib.rs:4:17 | 4 | let _: () = y; | ^ expected (), found reference | = note: expected type `()` found type `&&std::vec::Vec<{integer}>`
因此y
是&&Vec<i32>
。
这让我们看看let ref a = b;
通常相当于let a = &b;
,因此在这种情况下: let y = &&vec;
。
ref
是为了解构; 例如,如果你有:
let vec = Some(vec![1, 2, 3]);
if let Some(ref y) = vec {
// use `y` here
}
你可以在这里使用ref
能够将y
绑定到&Vec<i32>
而不移动,即使这里的vec
类型为Option<Vec<i32>>
。 实际上, ref
的目的是在解构期间在现有对象内部引用。
通常,在let
语句中,您不会使用ref
。
当在绑定的右端和左端使用时,相同的符号( &
)正在做两件不同的事情。 左侧的工作方式类似于模式匹配,因此:
let x = (y, z); // x contains a tuple with value (y, z)
let (a, b) = x // x is destructured into (a, b), so now
// a has value y and b has value z
以同样的方式
let x = &y; // x is a reference to y
let &z = x; // this is like let &z= &y, so we want z to be y
// this is equivalent to let z = *x
左侧的ref
绑定表示“参考模式匹配,而不是值”。 所以这两个陈述是等价的:
let ref y = vec;
let y = &vec;
虽然在一个让,第二个是更惯用。
首先,您不需要在工作示例中使用&
。 如果你使用它,你最终得到一个你不需要的&&Vec<_>
。
let vec = vec![1, 2, 3];
let ref y = vec;
您的第一个代码的问题是您一次做两件事。 让我们把它分成两部分:
第一部分创建了对vec
的引用
let y1 = &vec;
第二部分(变量绑定之前的&
), 解构 。
let &y2 = y1;
这意味着您正在尝试移出引用,该引用仅在类型为“ Copy
时才有效,因为任何移动尝试都将复制该对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.