问题 `&`和`ref`有什么区别?


我明白怎么做 & 有效,但有什么区别 ref?它们可以互换吗?

我发现的唯一信息(因为在Google上搜索符号效果不佳)是 关于Rust的例子,但它没有解释两者之间的区别。  信息量不大,而且 ref 只列在 模式 章节。但似乎是这样 ref 也在该上下文之外使用。

那么,有什么用呢? ref,有什么区别 &


7997
2017-10-18 23:25


起源

非常 相关的,但不完全是重复的,因为它不是之间的比较 ref 和 &: stackoverflow.com/questions/27911656/... - Kroltan


答案:


ref 用于模式以绑定对a的引用 左值 (左值是一个值,您可以采用或多或少的地址)。

重要的是要理解模式从正常表达式“向后”,因为它们已经习惯了 解构 值。

这是一个简单的例子。假设我们有这个:

let value = 42;

我们可以绑定一个引用 value 有两种方式:

let reference1 = &value;
let ref reference2 = value;

在第一种情况下,我们使用 & 作为运营商采取的地址 value。在第二种情况下,我们使用 ref 模式来“解构”一个左值。在这两种情况下,变量的类型都是 &i32

& 也可以在模式中使用,但它恰恰相反:它通过解除引用来解构引用。假设我们有:

let value = 42;
let reference = &value;

我们可以解除引用 reference 有两种方式:

let deref1 = *reference;
let &deref2 = reference;

这里,两者的类型 deref1 和 deref2 是 i32

但是,并不总是可以用两种方式编写相同的表达式。例如,你不能使用 & 引用存储在枚举变体中的值:您需要匹配它。例如,如果要引用a中的值 Some,你需要写:

match option {
    Some(ref value) => { /* stuff */ }
    None => { /* stuff */ }
}

因为在Rust中没有办法可以使用 & 运算符以其他方式访问该值。


12
2017-10-18 23:36



谢谢,所以定义如 fn blah(ref a: i32) {} 相当于 fn blah(a: &i32),当他们都可以表达? - Kroltan
@Kroltan不,他们不相同。一种模式(即,左边的任何东西) :)在函数参数中纯粹是一个实现细节,调用者只能看到类型(即,右边的东西) :)。第一种情况相当于 fn blah(tmp: i32) { let ref a = tmp; ... }。第一个被称为 blah(0) 而第二个被称为 blah(&1)。当然,功能本身的类型 a 是 &i32 在这两种情况下,它只是外部接口的不同。 - huon
@ huon-dbaupp,这是否意味着ref变体将首先复制/移动值? - Kroltan
fn blah(ref a: i32) -> {} 大致相当于 fn blah(temp_a: i32) { let ref a = temp_a; }。 - Eli Friedman