2015-12-18 11 views
6

Sto provando a creare due strutture che operano su un set di dati sottostante; uno che fornisce operazioni di "lettura" immutabili, l'altro che consente la modifica. Perché ciò funzioni, devo essere in grado di utilizzare le funzioni di lettura dall'interno dell'oggetto di modifica - in quanto tale, creo un nuovo oggetto di lettura temporaneo all'interno della funzione modificatore con una vista sui dati sottostanti.Passaggio di durata dei campi di riferimento sottostanti?

Ecco po 'di codice:

struct Read<'db> { 
    x: &'db i32 
} 

impl<'db> Read<'db> { 
    pub fn get(&'db self) -> &'db i32 { self.x } 
} 

struct Write<'db> { 
    x: &'db mut i32 
} 

impl<'db> Write<'db> { 
    fn new(x: &mut i32) -> Write { Write{x: x} } 

    fn as_read(&'db self) -> Read<'db> { 
     Read{x: self.x} 
    } 

    pub fn get(&'db self) -> &'db i32 { self.as_read().get() } 
}  


fn main() { 
    let mut x = 69i32; 
    let y = Write::new(&mut x); 
    println!("{}", y.get()); 
} 

Esso non può essere compilato - sembra che nonostante i miei sforzi, la vita del riferimento restituito da Read::get è destinato a portata s' il Write::get, piuttosto che il Write è 'db durata. Come posso compilarlo? (E, è quello che voglio fare? È il modo più semplice/conciso di farlo?)

risposta

4

Il punto che il compilatore sta cercando di trasmettere è che &'db self significa in realtà self: &'db Write<'db>. Ciò significa che leghi il riferimento AND il tipo alla stessa durata. Quello che vuoi veramente nel tuo caso è self: &'a Write<'db> dove 'a vive solo per la funzione as_read. Per poter restituire un riferimento 'db da un riferimento 'a, è necessario specificare che le vite 'a almeno fino a 'db vincolando 'a: 'db.

fn as_read<'a: 'db>(self: &'a Write<'db>) -> Read<'db> { 
    Read{x: self.x} 
} 

pub fn get<'a: 'db>(self: &'a Write<'db>) -> &'db i32 { self.as_read().get() } 

o più conciso

fn as_read<'a: 'db>(&'a self) -> Read<'db> { 
    Read{x: self.x} 
} 

pub fn get<'a: 'db>(&'a self) -> &'db i32 { self.as_read().get() } 

Try it out in the Playground

+0

Quello che è strano è che se lo struct non memorizza un '& mut', allora [non è necessario il 'a'' affatto] (http://is.gd/pbhLxP). Sembra un po 'strano. – Shepmaster

+0

Niente affatto. Se potessi chiamare 'as_read()' più volte, finirai con due '& mut' sull'i32. Puoi vedere che puoi usare il codice di @ Wavin se ti rimandi come immutabile in 'as_read': http://is.gd/Nt66hL questa sarebbe probabilmente la risposta migliore. Aggiornerò il mio codice –

+0

* finirebbe con due & mut per l'i32 * - Mi manca come. Dal momento che 'Read' memorizza solo un riferimento immutabile, mi aspetto che il mutevole -> reindirizzamento immutabile avvenga automaticamente. Inoltre I ** totalmente ** ha fatto '& * self.x' e non ha funzionato. Ora sto impazzendo. – Shepmaster

Problemi correlati