2016-01-11 16 views
5

このコードで何が問題になっていますか?この場合、refと&の違いは何ですか?

let vec = vec![1, 2, 3]; 
let &y = &vec; 

error: cannot move out of borrowed content 
let &y = &vec; 
note: attempting to move value to here 
let &y = &vec; 

なぜこれが正しいですか?

let vec = vec![1, 2, 3]; 
let ref y = &vec; 

答えて

5

パターン;ためには)

あなたがlet _:() = ...;トリックを使用することができ、コンパイラが何をするのか理解します。タイプ()の変数に代入することにより、変数に対して推論された型を示すエラーメッセージがコンパイラに出力されます。最初の例で


let vec = vec![1, 2, 3]; 
let &y = &vec; 
let _:() = y; 

我々が得る:

<anon>:5:17: 5:18 error: mismatched types: 
expected `()`, 
    found `collections::vec::Vec<_>` 
(expected(), 
    found struct `collections::vec::Vec`) [E0308] 
<anon>:5  let _:() = y; 
         ^
<anon>:5:17: 5:18 help: see the detailed explanation for E0308 

yのタイプはVec<i32>です。

  1. 借入vecvecは既に借りているので、禁止され、yvecを移動しようとすると、
  2. 一時的
  3. に:それは何を意味

    は、あなたがしていることです。

等価正しいコードは次のようになります

let vec = vec![1, 2, 3]; 
let ref y = &vec; 
let _:() = y; 

我々が得る:第2の例で

let vec = vec![1, 2, 3]; 
let y = vec; 

<anon>:5:17: 5:18 error: mismatched types: 
expected `()`, 
    found `&&collections::vec::Vec<_>` 
(expected(), 
    found &-ptr) [E0308] 
<anon>:5  let _:() = y; 
         ^
<anon>:5:17: 5:18 help: see the detailed explanation for E0308 

したがって、yは、&&Vec<i32>である。

これは、let ref a = b;が一般にlet a = &b;と等価であることを示しているので、この場合はlet y = &&vec;です。

refは、非構造化のために作られています。たとえば、あなたが持っていた場合:

let vec = Some(vec![1, 2, 3]); 
if let Some(ref y) = vec { 
} 

をあなたはここでvecOption<Vec<i32>>を入力しているにもかかわらず、移動せずにyにバインドできるようにするには、ここでrefを使用します。確かに、refの目的は、中に参照内の既存のオブジェクトを取ることです。

一般にletの文では、refは使用しません。

+0

上でより多くの例を見ることができ、我々は 'てみましょう&Y = &vec;'のようなものを使用したい合法的なケースはありますか? – WiSaGaN

+0

@WiSaGaN:私は考えることができません。 –

+0

@WiSaGaN:この構造は、たとえばクロージャーで使用できます。 Vecなどの関数の保持に使用されています。 –

1

まず、動作例では&は必要ありません。あなたがそれを使用するならば、あなたは本当に必要ではない&&Vec<_>になります。

let vec = vec![1, 2, 3]; 
let ref y = vec; 

最初のコードの問題は、一度に2つのことを行うことです。二つにそれを分割することができます:

最初の部分は、destructures(結合可変前&vec

let y1 = &vec; 

第二の部分への参照を作成します。

let &y2 = y1; 

これは、移動しようとするが、代わりにオブジェクトをコピーしますので、あなたは、タイプがCopyある場合のみ動作し、参照、の外に移動しようとしていることを意味します。一部に使用して得ることができる結合

2

バインディングの右端と左端に同じ記号(&)を使用すると、2つの異なることが起こります。左側ので、パターンマッチングのように動作:同様に

let x = (y, z); // x contains a tuple with value (y, z) 
let (a, b) = x // x is destructured into (a, b), so now 
       // a has value y and b has value z 

let x = &y; // x is a reference to y 
let &z = x; // this is like let &z= &y, so we want z to be y 
      // this is equivalent to let z = *x 

左側に結合ref「が参照によってではなく、値によってパターンマッチ」を言っています。したがって、これらの2つのステートメントは同等です。

let ref y = vec; 
let y = &vec; 

ただし、2番目の文はより慣用的ですが。

あなたはpointers/ref chapter on rust by example

関連する問題