我了解&
的工作原理,但它和ref
之间有什么区别?它们可以互换使用吗?
我找到的唯一信息(因为在Google上搜索符号效果不佳)是来自Rust By Example的此页面,但它没有解释两者之间的区别。The Book 不是非常详细,而ref
仅在模式章节中列出。但似乎ref
也在该上下文之外使用。
那么,ref
有哪些用途,与&
有何差异?
我了解&
的工作原理,但它和ref
之间有什么区别?它们可以互换使用吗?
我找到的唯一信息(因为在Google上搜索符号效果不佳)是来自Rust By Example的此页面,但它没有解释两者之间的区别。The Book 不是非常详细,而ref
仅在模式章节中列出。但似乎ref
也在该上下文之外使用。
那么,ref
有哪些用途,与&
有何差异?
ref
用于模式匹配中,将一个引用绑定到一个(可以取地址的值,或多或少)。
重要的是要理解模式与常规表达式相反,因为它们用于解构值。
这里有一个简单的例子。假设我们有以下内容:
let value = 42;
我们有两种方法可以将一个引用绑定到value
:
let reference1 = &value;
let ref reference2 = value;
在第一个例子中,我们使用&
作为运算符来获取value
的地址。在第二个例子中,我们使用ref
模式来“解构”lvalue。在两种情况下,变量的类型是&i32
。
&
也可以用于模式匹配,但它的作用相反:通过取消引用来解构引用。假设我们有:let value = 42;
let reference = &value;
我们有两种方法可以取消引用reference
:
let deref1 = *reference;
let &deref2 = reference;
这里,deref1
和 deref2
的类型均为 i32
。
然而,并非所有表达式都能像此处所示一样以两种方式编写。例如,您无法使用 &
来引用枚举变量中存储的值:您需要将其匹配。例如,如果要引用 Some
中的值的引用,则需要编写:
match option {
Some(ref value) => { /* stuff */ }
None => { /* stuff */ }
}
因为在Rust中,除了使用&
操作符,没有其他访问该值的方法。
fn blah(ref a: i32) {}
这样的定义与 fn blah(a: &i32)
是等价的,因为它们都可以表示相同的含义。 - Kroltan:
左侧的任何内容)纯粹是实现细节,调用方只能看到类型(即 :
右侧的内容)。第一种情况相当于 fn blah(tmp: i32) { let ref a = tmp; ... }
。第一个函数被调用时使用 blah(0)
,而第二个函数被调用时使用 blah(&1)
。当然,对于函数本身,a
的类型在两种情况下都是 &i32
,只是外部接口不同。 - huonfn blah(ref a: i32) -> {}
大致相当于 fn blah(temp_a: i32) { let ref a = temp_a; }
。 - Eli Friedman
ref
和&
之间的比较:https://dev59.com/-Ibca4cB1Zd3GeqPa9a7 - Kroltan