Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 例如:ref模式_Rust - Fatal编程技术网

Rust 例如:ref模式

Rust 例如:ref模式,rust,Rust,我无法理解锈迹中的ref模式。我指的是 以下是我不理解的代码: let point = Point { x: 0, y: 0 }; let _copy_of_x = { // `ref_to_x` is a reference to the `x` field of `point` let Point { x: ref ref_to_x, y: _ } = point; // Return a copy of the `x` field of `point`

我无法理解锈迹中的
ref
模式。我指的是

以下是我不理解的代码:

let point = Point { x: 0, y: 0 };

let _copy_of_x = {
    // `ref_to_x` is a reference to the `x` field of `point`
    let Point { x: ref ref_to_x, y: _ } = point;

    // Return a copy of the `x` field of `point`
    *ref_to_x
};
我得到最后一个
let
表达式(?)是某种模式匹配。所以我的理解是
ref\u to_x
应该等于
0
,原始
点的
x

但是我不明白
ref
实际上做了什么。当我添加如下代码时:

println!("x: {}", point.x);
println!("ref_to_x: {}", ref_to_x);
println!("*ref_to_x: {}", *ref_to_x);
我总是得到
0
,所以似乎没有什么区别。不知何故,我希望
ref\u to\u x
有一个内存地址,而
*ref\u to\u x
可能再次是解引用值

我可以用
myx
替换
ref-ref\u to\u x
*ref\u to\u x
,代码仍然有效。有什么区别?
ref
到底做什么


编辑:在阅读了dbaupp的答案并使用
ref_to_x
*ref_to_x
进行了一些添加之后,事情变得更清楚了;不能将整数添加到
ref_to_x
,因为它是一个引用。我想我是被弄糊涂了,因为当你打印一个引用时,没有任何引用的指示。

ref
在匹配的内存块中创建一个指针,在这种情况下,
ref\u to\u x
直接指向存储
point.x
的内存,在本例中,这与写入
let ref_to_x=&point.x
相同

这种模式非常重要,因为它允许人们深入复杂的数据结构,而不会干扰所有权层次结构。例如,如果有
val:&Option
,则写入

match *val {
    Some(s) => println!("the string is {}", s),
    None => println!("no string"
}
不合法,会出现如下错误:

<anon>:3:11: 3:15 error: cannot move out of borrowed content
<anon>:3     match *val {
                   ^~~~
<anon>:4:14: 4:15 note: attempting to move value to here
<anon>:4         Some(s) => {}
                      ^
<anon>:4:14: 4:15 help: to prevent the move, use `ref s` or `ref mut s` to capture value by reference
<anon>:4         Some(s) => {}
                      ^
:3:11:3:15错误:无法移出借用的内容
:3匹配*val{
^~~~
:4:14:4:15注意:正在尝试将值移动到此处
:4部分=>{}
^
:4:14:4:15帮助:要防止移动,请使用'ref s'或'ref mut s'通过引用捕获值
:4部分=>{}
^
从借用的值中取得所有权(移动)是不合法的,因为这可能会损坏借用该值的对象(违反其不变量,导致数据意外消失等)

因此,我们可以使用一个引用,通过借用
&
引用,只指向内存中的某个点



这里有一点微妙之处,因为(a)
不是借来的,所以可以移出
(这也会消耗
的所有权,意味着除非重新初始化,否则以后不能使用它)和(b)类型
int
Copy
,因此在按值使用时不会移动所有权。这就是为什么使用
myx
效果很好的原因。如果
x
的类型是,比如说,
String
(这不是
Copy
)如果借用了
,则需要
参考

使用
参考
创建的参考与使用
获取的参考完全相同

不同之处在于语法中允许它们的位置。作业左侧的
ref
类似于在右侧添加
&

这些表达式是等效的:

let ref x1 = y;
let x2 = &y;
这种冗余的存在是因为模式匹配中的
&
用于要求引用已经存在,而不是创建新引用:

let foo = 1;
match foo {
   ref x => {
       /* x == &1 */ 
       match x {
           &y => /* y == 1 */
       }
   },  
}
()