2015-01-12 9 views
5

私は錆でrefパターンを理解する問題を抱えています。 (?)私は最後let式はパターンマッチングのいくつかの並べ替えであることを取得錆は: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 
}; 

:私はここにhttps://rustbyexample.com/scope/borrow/ref.html

に私は理解していないコードされて参照しています。だから、それは私の理解ref ref_to_xだ、オリジナルpointx0に等しくなければなりません。

しかし、私はrefが実際に何をするかを理解していません。私はこのようないくつかのコードを追加する場合:

println!("x: {}", point.x); 
println!("ref_to_x: {}", ref_to_x); 
println!("*ref_to_x: {}", *ref_to_x); 

は、私はいつも0を取得し、その違いがあるようには思えません。何とか私はref_to_xのメモリアドレスを期待していましたが、*ref_to_xは逆参照されるかもしれません。

ref ref_to_x*ref_to_xの両方をmyxと置き換えることができ、コードは引き続き動作します。違いは何ですか? refは何をしますか?

編集:dbauppsの回答を読んで、ref_to_x*ref_to_xでいくつかの追加をした後、少し物事がはっきりしました。 ref_to_xに整数を追加することはできません。私はあなたが1つを印刷するときに参照の兆候がないので、私は混乱していると思う。 ref_to_xpoint.xを格納するメモリに直接指している

答えて

10

refがオンに一致しているメモリの部分へのポインタを作成し、この場合、それは、この場合let ref_to_x = &point.xの書き込みと同じです。それは1が所有階層を乱すことなく、深い複雑なデータ構造体の内側に到達することを可能にするよう

パターンは、非常に重要です。ので、借りた値のうち所有権(移動)を取ることが有効ではありません

<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) => {} 
        ^

:1が

match *val { 
    Some(s) => println!("the string is {}", s), 
    None => println!("no string" 
} 

が合法でない書き込みval: &Option<String>が、持っている場合たとえば、それはのようなエラーが発生しますその値が借用されたものを損なう可能性があります(その不変量を侵害し、予期しないデータが消えるなど)。

ので、1の代わりに借入&参照してメモリにだけポイントへの参照を使用することができます。


(a)のpointが借りていないので、(それを意味する、あまりにもpointの所有権を消費し再初期化しない限り、後に使用することができない)pointの外に移動してOKですので、多少の繊細は、ここにあります(b)タイプintCopyであるため、値で使用するとオーナーシップを移動しません。このため、代わりにmyxを使用すると正常に動作します。 xのタイプであった場合、String(これはCopyではありません)とpoint借りた後、refが必要になる、と言います。

11

refで作成された参照は、&で撮影された基準と全く同じです。それらは構文で許されている場所

違いがあります。割り当ての左側ref右側に&を加えるようなものです。 (

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

:新しいものにするためにではなく、&パターンマッチングの参照が既に存在することを要求するために使用されているので

let ref x1 = y; 
let x2 = &y; 

この冗長性が存在する:

これらの式は等価ですdiscussion