Rust                
            Auto-dereferenziazione
        
        
            
    Ricerca…
L'operatore punto
 Il . l'operatore di Rust ha un sacco di magia! Quando si utilizza . , il compilatore inserirà tante * s (operazioni di dereferenziamento) necessarie per trovare il metodo lungo la "struttura" del deref. Dato che questo accade al momento della compilazione, non vi è alcun costo di runtime per trovare il metodo. 
let mut name: String = "hello world".to_string();
// no deref happens here because push is defined in String itself
name.push('!');
let name_ref: &String = &name;
// Auto deref happens here to get to the String. See below
let name_len = name_ref.len();
// You can think of this as syntactic sugar for the following line:
let name_len2 = (*name_ref).len();
// Because of how the deref rules work,
// you can have an arbitrary number of references. 
// The . operator is clever enough to know what to do.
let name_len3 = (&&&&&&&&&&&&name).len();
assert_eq!(name_len3, name_len);
 La dereferenziazione automatica funziona anche per qualsiasi tipo che implementa std::ops::Deref trait. 
let vec = vec![1, 2, 3];
let iterator = vec.iter();
 Qui, iter non è un metodo di Vec<T> , ma un metodo di [T] . Funziona perché Vec<T> implementa Deref con Target=[T] che consente a Vec<T> trasformarsi in [T] quando viene deferito dall'operatore * (che il compilatore può inserire durante a . ). 
Deref coercizioni
 Dati due tipi T e U , &T costringerà (implicitamente convertito) a &U se e solo se T implementa Deref<Target=U> 
Questo ci permette di fare cose come questa:
fn foo(a: &[i32]) {
    // code
}
fn bar(s: &str) {
    // code
}
let v = vec![1, 2, 3];
foo(&v); // &Vec<i32> coerces into &[i32] because Vec<T> impls Deref<Target=[T]>
let s = "Hello world".to_string();
let rc = Rc::new(s);
// This works because Rc<T> impls Deref<Target=T> ∴ &Rc<String> coerces into 
// &String which coerces into &str. This happens as much as needed at compile time.
bar(&rc); 
Utilizzo di Deref e AsRef per argomenti di funzione
Per le funzioni che richiedono una raccolta di oggetti, le sezioni sono in genere una buona scelta:
fn work_on_bytes(slice: &[u8]) {}
 Perché Vec<T> e matrici [T; N] implementa Deref<Target=[T]> , possono essere facilmente forzati a una sezione: 
let vec = Vec::new();
work_on_bytes(&vec);
let arr = [0; 10];
work_on_bytes(&arr);
let slice = &[1,2,3];
work_on_bytes(slice); // Note lack of &, since it doesn't need coercing
Tuttavia, invece di richiedere esplicitamente una slice, la funzione può essere fatta per accettare qualsiasi tipo che possa essere usato come slice:
fn work_on_bytes<T: AsRef<[u8]>>(input: T) {
    let slice = input.as_ref();
}
 In questo esempio la funzione work_on_bytes prenderà qualsiasi tipo T che implementa as_ref() , che restituisce un riferimento a [u8] . 
work_on_bytes(vec);
work_on_bytes(arr);
work_on_bytes(slice);
work_on_bytes("strings work too!");
Implementazione di Deref per la struttura Option e wrapper
use std::ops::Deref;
use std::fmt::Debug;
#[derive(Debug)]
struct RichOption<T>(Option<T>); // wrapper struct
impl<T> Deref for RichOption<T> {
    type Target = Option<T>; // Our wrapper struct will coerce into Option
    fn deref(&self) -> &Option<T> {
        &self.0 // We just extract the inner element
    }
}
impl<T: Debug> RichOption<T> {
    fn print_inner(&self) {
        println!("{:?}", self.0)
    }
}
fn main() {
    let x = RichOption(Some(1)); 
    println!("{:?}",x.map(|x| x + 1)); // Now we can use Option's methods...
    fn_that_takes_option(&x); // pass it to functions that take Option...
    x.print_inner() // and use it's own methods to extend Option
}
fn fn_that_takes_option<T : std::fmt::Debug>(x: &Option<T>) {
    println!("{:?}", x)
}
Semplice esempio di Deref
 Deref ha una regola semplice: se hai un tipo T e implementa Deref<Target=F> , allora &T costringe a &F , il compilatore lo ripeterà tante volte quanto necessario per ottenere F, ad esempio: 
fn f(x: &str) -> &str { x }
fn main() {
    // Compiler will coerce &&&&&&&str to &str and then pass it to our function
    f(&&&&&&&"It's a string"); 
}
 La forzatura Deref è particolarmente utile quando si lavora con tipi di puntatore, come Box o Arc , ad esempio: 
fn main() {
    let val = Box::new(vec![1,2,3]);
    // Now, thanks to Deref, we still 
    // can use our vector method as if there wasn't any Box
    val.iter().fold(0, |acc, &x| acc + x ); // 6
    // We pass our Box to the function that takes Vec,
    // Box<Vec> coerces to Vec
    f(&val)
}
fn f(x: &Vec<i32>) {
    println!("{:?}", x) // [1,2,3]
}