ProgramlamaRust geliştirici, API/Kütüphane tasarımcısı

Dış türlerle (yetim kuralı) çalışırken Rust'taki trait'lerin çalışma şekli hakkında açıklama yapın. Sizin tarafınızdan tanımlanmamış bir tip için trait'i nasıl uygulayabilirsiniz ve bunun her zaman neden mümkün olmadığını açıklayın.

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap

Rust'ta bir tür için bir trait uygulamak yalnızca şu durumlarda izinlidir:

  • trait mevcut crate'te tanımlanmış olmalıdır VEYA
  • tür mevcut crate'te tanımlanmış olmalıdır.

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

İkna edici bir soru

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ı

Bilinçsizlikten kaynaklanan gerçek hata örnekleri


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.