繁体   English   中英

在从引用中分配变量时,ref和&之间的区别是什么?

[英]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>

这意味着你是:

  1. 借用vec成为临时的
  2. 试图将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

从Rust 1.26开始, 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM