O "Orada iyi bir neden", ama iyi bir neden o kadar karışık değil aşağı kaynatın gelmez.
İşte sorun. Bir kütüphane sandığım olduğunu düşünün:
// library.rs
pub struct Dog;
pub trait Speak {
fn speak(&self);
}
Ve bu kütüphane sandığını kullanan iki kasa.
// bark.rs
extern crate library;
impl library::Speak for library::Dog {
fn speak(&self) {
println!("woof");
}
}
// woof.rs
extern crate library;
impl library::Speak for library::Dog {
fn speak(&self) {
println!("bark");
}
}
Şimdi, bazı nedenlerden dolayı, ben bu kütüphanelerin her ikisini de kullanmak istiyorum:
// main.rs
extern crate library;
extern crate woof;
extern crate bark;
fn main() {
let rex = library::Dog;
rex.speak();
}
Ne bu program çıktısı gerekir? library::Dog
için library::Speak
iki eşit geçerli, ayırt edilemez uygulamaları vardır; doğru bir cevap yok. Daha da kötüsü, orijinal olarak woof
'a bağımlı olsaydım ve daha sonra bark
eklediyse, kodum derlemeyi durdurdu, veya - daha kötüsü - yanlış şeyi şeffaf bir şekilde yapmaya başlıyordu. Çakışan özellik impls bir Bad Thing ™ 'dir.
Jenerik eklediğinizde kötüleşir. Eğer varsa:
// barkgeneric.rs
extern crate library;
impl<T> library::Speak for T {
fn speak(&self) {
println!("woof");
}
}
// woofgeneric.rs
extern crate library;
impl<T> library::Speak for T {
fn speak(&self) {
println!("bark");
}
}
Artık çelişkili özellik impls bir sonsuz numarası var. Whoops.
Bu sorunu önlemek için, yetim kurallarımız var. Yetim kurallarının düşüncesi, herhangi bir impl Trait for Type
'un bir ve sadece bir tane yerleştirilebildiğinden emin olmaktır. Bu şekilde, impl çatışmaları hakkında endişelenmek zorunda değiliz; Yetim kuralları doğru şekilde kurulursa, doğrudan imkansız olmalılar.
Kurallar şununla eşleşir: impl
türünde bir özellik olduğunda, özellik ya da türün geçerli sandıktan gelmesi gerekir. Bu, tüm çakışan örneklerimi işe yaramaz. woof.rs
library::Dog
için library::speak
'u uygulayamaz, çünkü bunların hiçbiri sandığından gelmez.
Aynı şekilde, [T; 4]
çünkü sandık gelmiyor ve rustc
Index<Bounded>
ya da sandık gelen sayılmaz karar verdi, değil impl<T> Index<Bounded> for [T; 4];
can.
Ancak, bu durumda Index<Bounded>
ürününüz sizden geldiği için impl Index<Bounded> for [i32; 4]
numaranızı iletir.Bu bir hata, ama aynı zamanda sadece amaçlanmış davranışı da mümkündür; Yetim kuralları burada belirttiğimden biraz daha karmaşıktır ve garip şekillerde etkileşimde olabilirler.
Daha ayrıntılı bilgi için bkz. rustc --explain E0117
, rustc --explain E0210
.
Burada sorun aslında yetim kural değil, tutarlılık kuralı :). Açıklamayı "rustc --explain E0210" ile kontrol edebilirsiniz. – kennytm
@kennytm: Bu bir cevap olmalı mı (biraz ayrıntı ile)? –