我在理解refRust中的模式时遇到了问题.我指的是https://rustbyexample.com/scope/borrow/ref.html
这是我不明白的代码:
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
};
Run Code Online (Sandbox Code Playgroud)
我得到的是最后一个let表达式(?)是某种模式匹配.所以我的理解ref ref_to_x应该等于原始0的x价值point.
但我不明白ref实际上是做什么的.当我添加这样的代码时:
println!("x: {}", point.x);
println!("ref_to_x: {}", ref_to_x);
println!("*ref_to_x: {}", *ref_to_x);
Run Code Online (Sandbox Code Playgroud)
我总是得到0,所以似乎没有区别.不知何故,我希望ref_to_xwhile 的内存地址*ref_to_x可能再次被取消引用.
我可以替换两个ref ref_to_x和*ref_to_x使用myx代码仍然有效.有什么不同?究竟ref做了什么?
编辑:阅读dbaupps答案,并做一些除了具有后ref_to_x和*ref_to_x事情变得有点清晰; 你不能添加一个整数,ref_to_x因为它是一个引用.我想我很困惑,因为打印时没有任何参考指示.
Kor*_*nel 15
创建的引用与使用的引用ref完全相同&.
区别在于它们在语法中被允许的位置.ref在作业的左侧就像添加&在右侧.
这些表达式是等效的:
let ref x1 = y;
let x2 = &y;
Run Code Online (Sandbox Code Playgroud)
存在这种冗余是因为模式匹配&用于要求已经存在引用,而不是创建新引用:
let foo = 1;
match foo {
ref x => {
/* x == &1 */
match x {
&y => /* y == 1 */
}
},
}
Run Code Online (Sandbox Code Playgroud)
(讨论)
huo*_*uon 11
ref creates a pointer into the piece of memory that is being matched on, in this case, ref_to_x is pointing directly to the memory that stores point.x, it is the same as writing let ref_to_x = &point.x in this case.
The pattern is extremely important, as it allows one to reach deep inside complicated data-structures without disturbing the ownership hierarchy. For example, if one has val: &Option<String>, writing
match *val {
Some(s) => println!("the string is {}", s),
None => println!("no string"
}
Run Code Online (Sandbox Code Playgroud)
is not legal, it gives an error like:
<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) => {}
^
Run Code Online (Sandbox Code Playgroud)
It is not legal to take ownership (move) out of a borrowed value, because that would possibly damage the thing from which the value was borrowed (violating its invariants, causing data to disappear unexpectedly, etc.).
So, one can instead use a reference to just point in the memory with a borrowing & reference.
There's a slight subtlety here because (a) point isn't borrowed, so it is OK to move out of point (which consumes ownership of point too, meaning it can't be used later unless reinitialised), and (b) the type int is Copy, so doesn't move ownership when used by value. This is why using myx instead works fine. If the type of x was, say, String (which isn't Copy) and point was borrowed, then the ref will be necessary.
| 归档时间: |
|
| 查看次数: |
2210 次 |
| 最近记录: |