2015-12-18 6 views
6

Próbuję utworzyć dwie struktury działające na bazowym zbiorze danych; jeden zapewnia niezmienne operacje "odczytu", drugi umożliwia modyfikację. Aby to działało, muszę mieć możliwość korzystania z funkcji odczytu z obiektu modyfikującego - jako taki utworzę tymczasowy nowy obiekt do odczytu w funkcji modyfikatora z widokiem na dane bazowe.Przechodzenie na okresy życia leżących u podstaw pól odniesienia?

Oto niektóre kodu:

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()); 
} 

To nie kompiluje - wydaje się, że mimo moich starań, okres odniesienia wrócił z Read::get jest zobowiązany do ZAKRES Write::get „s, zamiast Write Czas życia: 'db. Jak mogę go skompilować? (I, czy to jest to, co chcę zrobić? Czy jest to najprostszy/najbardziej zwięzły sposób na zrobienie tego?)

Odpowiedz

4

Punkt, który kompilator próbuje pokonać, oznacza, że ​​&'db self w rzeczywistości oznacza self: &'db Write<'db>. Oznacza to, że wiążesz referencję I typ z tym samym okresem życia. To, czego naprawdę chcesz w twoim przypadku to self: &'a Write<'db>, gdzie 'a żyje tylko dla funkcji as_read. Aby móc zwracać odwołanie 'db z odwołania 'a, należy określić, że 'a żyje co najmniej tak długo, jak 'db przez ograniczenie '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() } 

lub bardziej zwięźle

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

Co jest dziwne jest to, że jeśli struktura nie przechowywać '& mut', to [nie potrzebują' 'A' w ogóle] (http://is.gd/pbhLxP). To wydaje się trochę dziwne. – Shepmaster

+0

Wcale nie. Gdybyś mógł wywołać 'as_read()' wiele razy, skończyłbyś z dwoma '& mut' na I32. Możesz zobaczyć, że możesz użyć kodu @ Wavina, jeśli wrócisz do niezmiennego w 'as_read': http://is.gd/Nt66hL, to prawdopodobnie będzie lepszą odpowiedzią. Zaktualizuję mój kod –

+0

* skończysz z dwoma i zmusisz do i32 * - Muszę nie wiedzieć jak. Ponieważ 'Read' zachowuje tylko niezmienne odniesienie, spodziewam się, że zmienny -> immortable reborrow stanie się automatycznie. Również ja ** całkowicie ** zrobił '& * self.x' i to nie działało. Teraz zwariowałem. – Shepmaster

Powiązane problemy