2015-10-18 2 views
12

Ich verstehe, wie & funktioniert, aber was ist der Unterschied zwischen diesem und ref? Sind sie austauschbar? Die einzigen Informationen, die ich gefunden habe (weil die Suche nach Symbolen bei Google nicht sehr gut funktioniert) ist this page on Rust By Example, aber es erklärt nicht den Unterschied zwischen den beiden. The Book ist nicht sehr informativ, und ref ist nur auf dem Patterns Kapitel aufgeführt. Aber es scheint, dass ref auch außerhalb dieses Kontexts verwendet wird.Was ist der Unterschied zwischen `&` und `ref`?

Also, was sind die Verwendungen von ref, und was ist der Unterschied zu &?

+0

* Sehr * verwandt, aber nicht gerade ein Duplikat, da es kein comparsion zwischen 'ref' und' & ': http://stackoverflow.com/questions/27911656/rust-by-example-the-ref- Muster – Kroltan

Antwort

12

ref wird in Mustern verwendet, um eine Referenz an lvalue zu binden (ein lvalue ist ein Wert, den Sie die Adresse von mehr oder weniger nehmen können).

Es ist wichtig zu verstehen, dass Muster von normalen Ausdrücken "rückwärts" gehen, da sie Werte dekonstruieren.

Hier ist ein einfaches Beispiel. Angenommen, wir haben dies:

let value = 42; 

Wir einen Verweis auf value auf zwei Arten binden können:

let reference1 = &value; 
let ref reference2 = value; 

Im ersten Fall verwenden wir & als Operator die Adresse value zu nehmen. Im zweiten Fall verwenden wir das Muster ref, um einen L-Wert zu "dekonstruieren". In beiden Fällen ist der Typ der Variablen &i32.

& kann auch in Mustern verwendet werden, aber es tut das Gegenteil: Es dekonstruiert eine Referenz durch Dereferenzierung. Angenommen, wir haben:

let value = 42; 
let reference = &value; 

Wir können dereferenzieren reference auf zwei Arten:

let deref1 = *reference; 
let &deref2 = reference; 

hier die Art der beiden deref1 und deref2 ist i32.

Es ist nicht immer möglich, den gleichen Ausdruck auf zwei Arten zu schreiben, wie hier gezeigt, aber. Beispielsweise können Sie & nicht verwenden, um einen Verweis auf einen Wert in einer enum-Variante zu speichern: Sie müssen übereinstimmen. Zum Beispiel, wenn Sie einen Verweis auf den Wert in einem Some nehmen möchten, müssen Sie schreiben:

match option { 
    Some(ref value) => { /* stuff */ } 
    None => { /* stuff */ } 
} 

da es in Rust keine Möglichkeit Sie den & Operator verwenden können, um andernfalls den Wert zugreifen.

+0

Dank, so Definitionen wie 'fn blah (ref a: i32) {}' sind äquivalent zu 'fn bla (a: & i32)', wenn sie beide ausgedrückt werden kann? – Kroltan

+4

@Kroltan Nein, sie sind nicht gleichwertig. Ein Muster (d. H. Alles, was links vom ':' steht) in einem Funktionsargument ist ein reines Implementierungsdetail, Anrufer sehen nur die Typen (d. H. Dinge rechts vom ':').Der erste Fall ist äquivalent zu 'fn blah (tmp: i32) {let ref a = tmp; ...} '. Der erste heißt wie 'blah (0)', während der zweite wie 'blah (& 1)' heißt. Natürlich ist die Funktion selbst, die Art von "a" ist in beiden Fällen "& i32", es ist nur die externe Schnittstelle, die sich unterscheidet. – huon

+0

@ huon-dbaupp, bedeutet das, dass die Ref-Variante zuerst den Wert kopiert/verschiebt? – Kroltan