2015-10-18 14 views
12

Rozumiem, jak działa &, ale jaka jest różnica między tym a ref? Czy są wymienne?Jaka jest różnica między `&` a `ref`?

Jedyne informacje, które znalazłem (ponieważ wyszukiwanie symboli w Google nie działa zbyt dobrze) to this page on Rust By Example, ale nie wyjaśnia to różnicy między nimi. The Book nie zawiera zbyt wielu informacji, a numer ref jest wymieniony tylko w rozdziale Patterns. Ale wydaje się, że ref jest również używany poza tym kontekstem.

Więc, jakie są zastosowania ref i jaka jest różnica do &?

+0

* Bardzo * powiązany, ale nie do końca duplikat, ponieważ nie jest to porównanie pomiędzy 'ref' i' & ': http://stackoverflow.com/questions/27911656/rust-by-example-the-ref- wzór – Kroltan

Odpowiedz

12

ref jest używany w wzorach do wiązania odniesienia do lwartość (lwartość to wartość, którą można uzyskać adres mniej więcej).

Ważne jest, aby zrozumieć, że wzorce przechodzą "w tył" od wyrażeń normalnych, ponieważ są używane do wartości dekonstrukcji.

Oto prosty przykład. Załóżmy, że mamy to:

let value = 42; 

Możemy powiązać odniesienie do value na dwa sposoby:

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

w pierwszym przypadku, używamy & jako operatora do podjęcia adres value. W drugim przypadku używamy wzoru ref do "dekonstrukcji" wartości l. W obu przypadkach typ zmiennej to &i32.

& może być również stosowany we wzorach, ale działa odwrotnie: dekonstruuje odniesienie, usuwając z niego odwołania. Załóżmy, że mamy:

let value = 42; 
let reference = &value; 

Możemy dereference reference na dwa sposoby:

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

tutaj typ zarówno deref1 i deref2 jest i32.

Nie zawsze jest możliwe zapisanie tego samego wyrażenia na dwa sposoby, jak pokazano tutaj. Na przykład nie można użyć wartości &, aby uzyskać odwołanie do wartości przechowywanej w wariancie wyliczenia: należy dopasować do niej. Na przykład, jeśli chcesz mieć odniesienie do wartości w Some, trzeba napisać:

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

ponieważ nie ma sposobu, w Rust można użyć operatora & aby uzyskać dostęp do wartości inaczej.

+0

Dzięki, więc definicje takie jak 'fn blah (ref a: i32) {}' są równoważne 'fn blah (a: i i32)', kiedy można je wyrazić? – Kroltan

+4

@Kroltan Nie, nie są one równoważne. Wzorzec (tzn. Cokolwiek na lewo od ':') w argumencie funkcji jest czysto szczegółem implementacji, wywołujący widzi tylko typy (to znaczy rzeczy po prawej stronie ':').Pierwszy przypadek jest równoważny 'fn blah (tmp: i32) {let ref a = tmp; ...} '. Pierwszy nazywa się "bla (0)", podczas gdy drugi nazywa się "bla (& 1)". Oczywiście sama funkcja, typ 'a' to w obu przypadkach' & i32', to tylko zewnętrzny interfejs, który się różni. – huon

+0

@ huon-dbaupp, czy to oznacza, że ​​wariant ref skopiuje/przeniesie wartość jako pierwszą? – Kroltan

Powiązane problemy