Rust'ta bir tür için bir trait uygulamak yalnızca şu durumlarda izinlidir:
Bu koşullara yetim kuralı (orphan rule) denir. Bu, bağımsız olarak aynı trait'in aynı tür için farklı crate'lerde uygulanması durumunda çakışmaları önler.
Eğer bir dış tür için dış bir trait'i uygulamak istiyorsanız — bu doğrudan mümkün değildir. Genellikle "newtype" modeli kullanılır: türü kendi yapınıza sarın ve ardından kendi türünüz için trait'i uygulayın.
Örnek:
// Dış tür ve dış trait (bizim crate'imizde değil) // struct ExternalType; trait ExternalTrait { ... } struct MyWrapper(ExternalType); impl ExternalTrait for MyWrapper { /* ... */ } // Artık sarmalama üzerinden çalışıyoruz
Soru: İki taraflı olarak her ikisi de kamuya açık olan bir dış trait'i dış bir tür için kullanarak use ve impl aracılığıyla uygulamak mümkün müdür?
Yanlış cevap: Evet, kendi crate'imizde bir impl bildirmek yeterlidir, her şey çalışacaktır.
Doğru cevap: Hayır, bu durumda derleyici izin vermez. Bir trait veya tür mevcut crate'te tanımlanmadıkça trait'i uygulamak mümkün değildir. Aksi takdirde — yetim kuralı hatası (orphan rule error) olur.
Hata örneği:
// extern crate other; // impl Display for other::ExternalType { ... } // Yetim kuralı hatası
Hikaye
Takım, dış bir trait'in
impl'i aracılığıyla dış bir günlük kaydına destek ihtiyacı duydu. Üçüncü taraf türü için uygulama girişimi, yetim kuralı hatasına ve sebepler üzerine uzun tartışmalara yol açtı. Sonunda, mimariyi newtype modeline göre değiştirmek zorunda kaldılar.
Hikaye
Açık kaynak proje, başka bir kütüphaneden bir yapı için Debug uygulamaya karar verdi, ancak bu yetim kuralı tarafından engellendi. Sonuç olarak kullanıcılar, rahatsız edici çözümler ile çalışmak zorunda kaldı ve kendi sarma işlemlerini yazmak zorunda kaldılar.
Hikaye
Ciddi bir hata: Dış bir enum için FromStr uygulamaya çalışırken string'den ayrıştırmak üzere derleyici yetim kuralını geçiremedi. Geliştirici, hafızada unsafe dönüşümlerle durumu "çözdü", bu da üretimde UB'ye neden oldu.