ref 和 & 和有什么不一样?从引用分配变量时? [英] What's the difference between ref and & when assigning a variable from a reference?
问题描述
这段代码有什么问题?
fn 示例() {让 vec = vec![1, 2, 3];让 &_y = &vec;}
error[E0507]: 不能移出借来的内容-->src/lib.rs:3:15|3 |让 &_y = &vec;|--- ^^^^ 不能移出借来的内容|||||数据移到这里|帮助:考虑删除 `&`: `_y`|注意:发生移动是因为 `_y` 的类型是 `std::vec::Vec`,它没有实现 `Copy` trait-->src/lib.rs:3:10|3 |让 &_y = &vec;|^^
为什么这是正确的?
let vec = vec![1, 2, 3];让 ref _y = &vec;
模式绑定可以得到一些使用 ;)
为了理解编译器的作用,您可以使用 let _: () = ...;
技巧.通过分配给 ()
类型的变量,您可以强制编译器打印一条错误消息,为您提供它为您的变量推断的类型.
在第一个例子中:
let vec = vec![1, 2, 3];让 &y = &vec;让 _: () = y;
我们得到:
<块引用>错误[E0308]:类型不匹配-->src/lib.rs:4:13|4 |让 _: () = y;|^ 预期 (),找到结构体`std::vec::Vec`|= 注意:预期类型`()`找到类型 `std::vec::Vec<{integer}>`
y
的类型是 Vec
.
这意味着你是:
- 借用
vec
到一个临时的 - 试图将
vec
移动到y
中,这是被禁止的,因为vec
已经被借用了.
等效的正确代码是:
let vec = vec![1, 2, 3];让 y = vec;
<小时>
在第二个例子中:
let vec = vec![1, 2, 3];让 ref y = &vec;让 _: () = y;
我们得到:
<块引用>错误[E0308]:类型不匹配-->src/lib.rs:4:17|4 |让 _: () = y;|^ 预期 (),找到参考|= 注意:预期类型`()`找到类型 `&&std::vec::Vec<{integer}>`
因此 y
是 &&Vec
.
这让我们看到 let ref a = b;
通常等价于 let a = &b;
,因此在这种情况下:lety = &&vec;
.
ref
用于解构;例如,如果您有:
let vec = Some(vec![1, 2, 3]);如果让 Some(ref y) = vec {//在这里使用 `y`}
您可以在此处使用 ref
来将 y
绑定到 &Vec
而无需尽管 vec
在这里的类型为 Option
.事实上,ref
的目的是在解构过程中引用inside 现有对象.
一般来说,在let
语句中,不会使用ref
.
并且从 Rust 1.26 开始,ref
在模式匹配中被推断出来;请参阅比赛人体工程学的稳定性.
What is wrong with this code?
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;
| ^^
and why this is correct?
let vec = vec![1, 2, 3];
let ref _y = &vec;
Pattern binding can get some using to ;)
In order to understand what the compiler does, you can use the let _: () = ...;
trick. By assigning to a variable of type ()
, you force the compiler to print an error message giving you the type it inferred for your variable.
In the first example:
let vec = vec![1, 2, 3];
let &y = &vec;
let _: () = y;
we get:
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}>`
the type of y
is Vec<i32>
.
What it means is that you are:
- Borrowing
vec
into a temporary - Attempting to move
vec
intoy
, which is forbidden becausevec
is already borrowed.
The equivalent correct code would be:
let vec = vec![1, 2, 3];
let y = vec;
In the second example:
let vec = vec![1, 2, 3];
let ref y = &vec;
let _: () = y;
we get:
error[E0308]: mismatched types --> src/lib.rs:4:17 | 4 | let _: () = y; | ^ expected (), found reference | = note: expected type `()` found type `&&std::vec::Vec<{integer}>`
Thus y
is &&Vec<i32>
.
This let us see that let ref a = b;
is generally equivalent to let a = &b;
, and therefore in this case: let y = &&vec;
.
ref
is made for destructuring; for example, if you had:
let vec = Some(vec![1, 2, 3]);
if let Some(ref y) = vec {
// use `y` here
}
you can use ref
here to be able to bind y
to &Vec<i32>
without moving even though vec
here has type Option<Vec<i32>>
. Indeed, the purpose of ref
is to take a reference inside an existing object during destructuring.
In general, in a let
statement, you will not use ref
.
And since Rust 1.26, ref
is inferred in pattern matching; see the stabilization of match ergonomics.
这篇关于ref 和 & 和有什么不一样?从引用分配变量时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!