2016-12-26 27 views
7

İlişkili tür kullanmayla ilişkili olarak, aşağıdaki iki benzer program tarafından gösterilen, hata olmadan derleyen ve ikincisi bulunan ömür boyu hata.Yaşam boyu parametresiyle ilişkili özellik türünü kullanan ömür boyu hata

Programı # 1 - hatasız derler

trait Trait<'a> { 
    type T; 
} 

struct Impl; 

impl<'a> Trait<'a> for Impl { 
    type T = std::marker::PhantomData<&'a()>; 
} 

struct Alpha<'a, T: Trait<'a>> { 
    _dummy: std::marker::PhantomData<(&'a(), T)>, 
} 

fn use_alpha<'a>(_: &'a Alpha<'a, Impl>) {} 

fn main() { 
    for x in Vec::<Alpha<Impl>>::new().into_iter() { 
     use_alpha(&x); // <-- ok 
    } 
} 

Programı # 2 - yaşam boyu hatası Burada

trait Trait<'a> { 
    type T; 
} 

struct Impl; 

impl<'a> Trait<'a> for Impl { 
    type T = std::marker::PhantomData<&'a()>; 
} 

struct Alpha<'a, T: Trait<'a>> { 
    _dummy: std::marker::PhantomData<(&'a(), T::T)>, 
} 

fn use_alpha<'a>(_: &'a Alpha<'a, Impl>) {} 

fn main() { 
    for x in Vec::<Alpha<Impl>>::new().into_iter() { 
     use_alpha(&x); // <-- !error! 
    } 
} 

sahiptir ikinci program için derleme zamanı hatası var:

error: `x` does not live long enough 
    --> src/main.rs:20:5 
    | 
19 |   use_alpha(&x); // <-- !error! 
    |     - borrow occurs here 
20 |  } 
    | ^`x` dropped here while still borrowed 
    | 
    = note: values in a scope are dropped in the opposite order they are created 

Burada iki program için fark verilmiştir:

#[derive(Clone)] 
struct Alpha<'a, T: Trait<'a>> { 
- _dummy: std::marker::PhantomData<(&'a(), T)>, 
+ _dummy: std::marker::PhantomData<(&'a(), T::T)>, 
} 

tek fark ilk programı değiştirerek ilişkili bir türü yerine struct tanımı tür parametresini kullanımı, yani bir kullanım süresi hatası oluşur. Bunun neden olduğu hakkında hiçbir fikrim yok. Anlatabildiğim kadarıyla, ilişkili tür herhangi bir ek ömür sınırlaması getirmemelidir - hepsi sadece 'a, ama Rust derleyicisi aynı fikirde değildir.

İkinci programın basit örnekleme ile main işlevinde yinelemeyi değiştirirsem, o zaman ömür boyu hata gider. Yani: yineleme direkt örnekleme daha farklı olmasının nedeni anlamıyorum

fn main() { 
    let x = Alpha::<Impl> { _dummy: std::marker::PhantomData }; 
    use_alpha(&x); // <-- ok in both programs 
} 

.

+0

Hala bunu denemeye çalışıyorum. Ama ben _did_ '' in_iter() 'yerine' iter() 'i kullanabileceğinizi ve işe yarayacağını buldum. –

cevap

4

use_alpha'da, Alpha referansı ve ömür boyu parametresi için aynı yaşam süresini kullandınız. Ömür boyu parametresi, daha sonra Impl'un Trait::T'un ömrü olur. Not, değerlerin düşürülmesi sırasına ilişkin bir ipucu verir: Impl'un tanımı, Impl'un tanımının bir parçası olduğu için Impl::T düşürülür, ancak bu, Alpha'un bazı bölümlerinin hala etrafta iken düştüğü anlamına gelir.

Sen use_alpha yılında İki yaşam parametreleri kullanarak bu sorunu giderebilirsiniz: Bu derleyici türlerinin her biri için farklı yaşam süresi anlaması sağlayacak

fn use_alpha<'a, 'b>(_: &'a Alpha<'b, Impl>) {} 

.

+0

4 saat sorulduktan sonra, beni dakikalar sonra bir cevapla yendiniz ... – Shepmaster

+2

@Shepmaster Sonunda! : P –

+0

Ayrıca, lütfen sitemizi de göndermekten çekinmeyin veya benimkileri düzenleyin. Açıklamalarımdan tamamen memnun değilim - kısmen kendimi anladığımdan emin değilim çünkü% 100. –

İlgili konular