İ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
}
.
Hala bunu denemeye çalışıyorum. Ama ben _did_ '' in_iter() 'yerine' iter() 'i kullanabileceğinizi ve işe yarayacağını buldum. –