2015-07-23 1 views
8

Se ho il seguente struct:Come si distruttura una tupla in modo che i binding siano modificabili?

struct MyStruct { tuple: (i32, i32) }; 

E la seguente funzione:

// This will not compile 
fn function(my_struct: &mut MyStruct) { 
    let (val1, val2) = my_struct.tuple; 
    val1 = 1; 
    val2 = 2; 
} 

Come faccio a prendere in prestito val1 e val2 come mutabile così quando ho riassegnare loro i cambiamenti appariranno nella struct originale?

risposta

9

Hai qualche problema:

  • Hai inserito lo &mut nel posto sbagliato; &mut è parte del tipo, non dell'argomento (a meno che tu non stia distruggendo l'argomento, che tu non sia).

  • Non è possibile chiamare l'argomento struct, poiché si tratta di una parola chiave.

  • Non è possibile assegnare a un riferimento modificabile con assegnazione diretta.

Così, con quelli in mente, ecco una soluzione di lavoro:

#[derive(Debug)] 
struct MyStruct { 
    tuple: (i32, i32), 
} 

fn function(s: &mut MyStruct) { 
    let (ref mut val1, ref mut val2) = s.tuple; 
    *val1 = 1; 
    *val2 = 2; 
} 

fn main() { 
    let mut s = MyStruct { tuple: (0, 0) }; 
    function(&mut s); 
    println!("{:?}", s); 
} 

La chiave qui è che ref in un modello lega per riferimento; combinandolo con mut si ottiene un riferimento mutabile. In particolare, ti dà un paio di &mut i32 s. Dato che si tratta di riferimenti, devi de-referenziarli per assegnarli attraverso di essi (altrimenti, staresti cercando di riassegnare il riferimento stesso).

8

Hai due domande leggermente diverse.

È possibile creare un vicolo cieco mutabile dicendo mut due volte:

fn main() { 
    let a = (1, 2); 
    let (mut b, mut c) = a; 
    b += 1; 
    c += 2; 

    println!("{}, {}", b, c); 
} 

Ma per avere cambia nella tupla originale, è necessario un mutabile riferimento in quella tupla:

fn main() { 
    let mut a = (1, 2); 

    { 
     let (ref mut b, ref mut c) = a; 
     *b += 1; 
     *c += 2; 
     // Let mutable borrows end 
    } 

    println!("{:?}", a); 
}