ref 和 & 和有什么不一样?从引用分配变量时? [英] What's the difference between ref and & when assigning a variable from a reference?

查看:42
本文介绍了ref 和 & 和有什么不一样?从引用分配变量时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这段代码有什么问题?

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.

这意味着你是:

  1. 借用 vec 到一个临时的
  2. 试图将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:

  1. Borrowing vec into a temporary
  2. Attempting to move vec into y, which is forbidden because vec 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 和 &amp; 和有什么不一样?从引用分配变量时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆