2015-12-18 12 views
6

Temel veri kümesinde çalışan iki yapı yapmaya çalışıyorum; biri değişmez "okuma" işlemleri sağlayan, diğeri değiştirmeye izin veren. Bunun çalışması için, okuma işlevlerini değiştirme nesnesinin içinden kullanabilmem gerekir. Bu nedenle, altta yatan verilere yönelik bir görünümle değiştirici işlevinde geçici bir yeni okuma nesnesi oluşturuyorum. İşte Temel referans alanlarının yaşam sürelerini mi geçmek istiyorsunuz?

bazı kod: Bu derleme değil

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

- oldukça Write daha benim en iyi çabalarına rağmen, Read::get döndü referans ömrü Write::get 'in kapsamına bağlı olduğu görünüyor 'db kullanım ömrü. Derlemeyi nasıl yapabilirim? (Ve bunu yapmak istediğim şey nedir? Bunu yapmanın en basit/en özlü yolu mu?)

cevap

4

Derleyicinin karşılaşmaya çalıştığı nokta, &'db self'un aslında self: &'db Write<'db> anlamına gelir. Bu, referansı VE türünü aynı kullanım ömrüne bağlamanız anlamına gelir. Durumunda aslında ne istiyorsun self: &'a Write<'db>'a sadece as_read işlevi için yaşıyor.referansını birreferansından alabilmek için, 'un en az'u 'a: 'db'u kısıtlayarak geçtiği belirtmeniz gerekir.

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

veya daha fazla öz

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

Ne garip yapı bir '& mut' saklamaz, o zaman [' 'a' gerek kalmamasıdır hiç) (http://is.gd/pbhLxP). Bu biraz garip görünüyor. – Shepmaster

+0

Hiç de değil. "As_read()" işlevini birden çok kez çağırırsanız, i32'ye iki "& mut" ile son verirsiniz. @ Wav'ın kodunu eğer 'as_read' içinde immutable olarak değiştirirseniz kullanabilirsiniz: http://is.gd/Nt66hL Bu muhtemelen daha iyi bir cevap olacaktır. –

+0

* kodumu güncelleyeceğim * i32 * ile iki & mut ile sonuçlanacaksınız - nasıl olması gerektiği konusunda eksik olmalıyım. 'Oku' sadece değişmez bir referansı sakladığından, değişebilir -> değişmez bir yarının otomatik olarak gerçekleşmesini beklerdim. Ayrıca ben ** tamamen ** yaptım * ve * self.x' ve işe yaramadı. Şimdi deliriyorum. – Shepmaster

İlgili konular