2016-01-11 12 views

Antwort

5

Muster Bindung kann einige mit bekommen;)

Um zu verstehen, was der Compiler tut, können Sie den let _:() = ...; Trick verwenden können. Wenn Sie eine Variable vom Typ () zuweisen, erzwingen Sie, dass der Compiler eine Fehlermeldung ausgibt, die Ihnen den Typ angibt, der für Ihre Variable abgeleitet wurde.


Im ersten Beispiel:

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

erhalten wir:

<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 

die Art der yVec<i32> ist.

Was es bedeutet, ist, dass Sie sind:

  1. Borrowing vec in eine temporäre
  2. Versuch vec in y zu bewegen, was verboten ist, weil vec bereits entliehen ist.

Der äquivalent würde richtige Code sein:

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

Im zweiten Beispiel:

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

erhalten wir:

<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 

Somit ist y&&Vec<i32>.

Dies lassen Sie uns sehen, dass let ref a = b; in der Regel let a = &b; entspricht und daher in diesem Fall: let y = &&vec;.

ref ist für die Destrukturierung gemacht; zum Beispiel, wenn Sie hatte:

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

Sie ref hier in der Lage sein zu binden y zu ohne bewegen, obwohl vec hier eingeben Option<Vec<i32>> hat verwenden würde. In der Tat ist der Zweck von ref, eine Referenz innerhalb eines existierenden Objekts während der Destrukturierung zu nehmen.

Im Allgemeinen werden Sie in einer let Anweisung ref nicht verwenden.

+0

Gibt es ein Legit Fall sehen, wo wir wie etwas verwenden wollen, 'lassen & y = &vec;'? – WiSaGaN

+0

@WiSaGaN: Ich kann mir keine vorstellen. –

+0

@WiSaGaN: Diese Konstruktion kann zum Beispiel in Verschlüssen verwendet werden. Es wird in der Funktion in Vec beibehalten und so weiter. –

1

Zunächst einmal brauchen Sie nicht die & in Ihrem Arbeitsbeispiel. Wenn Sie es verwenden, erhalten Sie am Ende eine &&Vec<_>, die Sie nicht wirklich benötigen.

Das Problem mit Ihrem ersten Code ist, dass Sie zwei Dinge gleichzeitig tun. Lässt sie aufgespalten in zwei:

Der erste Teil

let y1 = &vec; 

Der zweite Teil einen Verweis auf vec erzeugt (die & vor dem variable-Bindung), destructures.

let &y2 = y1; 

Dies bedeutet, dass Sie versuchen, aus dem Bezug zu bewegen, das funktioniert nur, wenn der Typ Copy ist, weil dann jeder Versuch, stattdessen das Objekt kopiert zu bewegen.

2

Das gleiche Symbol (&) macht zwei verschiedene Dinge, wenn es auf der rechten und linken Seite einer Bindung verwendet wird. Die linke Seite funktioniert wie ein Pattern-Matching, so:

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 

In gleicher Weise

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 

A ref auf der linken Seite Bindung "Mustererkennung durch Referenz, nicht von Wert" sagen . Also diese beiden Aussagen sind gleichwertig:

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

obwohl in einem Let, der zweite ist idiomatisch.

Sie können weitere Beispiele auf der pointers/ref chapter on rust by example

Verwandte Themen