ProgramlamaKütüphane Geliştiricisi

Rust'ta PartialEq ve Eq nedir, değerlerin karşılaştırılmasında hangi sözleşmeyi sağlarlar ve kullanıcı tanımlı türlerde eşitliğin titizliğini sağlamak neden önemlidir?

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

Cevap.

Konunun geçmişi

Rust'ta PartialEq ve Eq trait'leri, type safety felsefesinden doğar — koleksiyonlarla ilgili tüm temel işlemler (HashMap, HashSet) eşitliğin titiz bir tanımına dayanır. Bu trait'ler, iki tür nesnenin == ile karşılaştırılıp karşılaştırılamayacağını ve türün "tam" eşitlik (Eq) veya "kısmi" (PartialEq) sağlamak zorunda olup olmadığını belirler.

Sorun

PartialEq/Eq'nin yanlış uygulanması koleksiyonların düzgün çalışmamasına neden olur; burada temel matematiksel özellikler ihlal edilir: kendisiyle karşılaştırma, simetri, geçişkenlik. Ayrıca, hatalı bir Eq, nesnelerin koleksiyonlarda "kaybolmasına" veya beklenmedik kopyaların oluşmasına neden olabilir.

Çözüm

PartialEq, karşılaştırmanın tüm değerler için mümkün olmadığı türler için uygulanır (örneğin, f32, burada NaN != NaN). Eq yalnızca "titiz" (tam) ilişkiler için tasarlanmıştır. Kullanıcı tanımlı türler, bu sözleşmelere titizlikle uyarak karşılaştırmayı gerçekleştirmelidir.

Kod örneği:

#[derive(PartialEq, Eq)] struct Point { x: i32, y: i32, } let p1 = Point { x: 1, y: 2 }; let p2 = Point { x: 1, y: 2 }; assert!(p1 == p2); // true

Ana özellikler:

  • PartialEq "kısmi" karşılaştırmaya izin verir — bazı değerlerin doğru bir şekilde karşılaştırılmadığı durumlar olabilir (örneğin, NaN).
  • Eq, tam bir ilişki talep eder: x == x her zaman true olmalıdır; ilişki ile ilgili tüm özellikler sağlanmalıdır.
  • Bu trait'lerin doğru uygulanması, koleksiyonlar ve standart kütüphane işlevleri için kritiktir.

Zorlayıcı sorular.

Neden f32 türü için standart kütüphane sadece PartialEq, ancak Eq'yi uygulamıyor?

Çünkü IEEE-754'e göre NaN != NaN, yani tüm x için x == x özelliği sağlanmamaktadır ve bu da Eq için gerekli bir özelliktir.

Eğer PartialEq manuel olarak uygulanmışsa, Eq'yi açıkça uygulamak zorunlu mu?

Evet, eğer tür tam eşitliği destekliyorsa (x == x her zaman true), Eq'nin de manuel olarak uygulanması gerekmektedir, aksi takdirde bazı yapılar sizin türünüzle derlenmeyecektir.

Kullanıcı, PartialEq'yi "asimetrik" olarak (x == y, ancak y != x) uygulayabilir mi?

Teknik olarak evet, ancak bu koleksiyonların düzgün çalışmamasına yol açar ve bir hata olarak kabul edilir.

Tipik hatalar ve anti-patternler

  • Gerekli karşılaştırma özelliklerini göz ardı ederek PartialEq'nin "hatalı" uygulanması.
  • Mümkün olan durumlarda Eq'yi uygulamamak ve HashMap/HashSet'ın çalışmasını bozmak.
  • Spesifikasyonu ihlal ederek simetriyi "kendine göre" uygulamak.

Gerçek hayattan örnek

**Olumsuz örnek

Kullanıcı, yalnızca bir alan üzerinden karşılaştırma yapan bir tür için PartialEq'yi uyguladı, diğer alanlar göz ardı edildi. Sonuç olarak, HashSet "kopyaları kaybetti".

Artılar:

  • Basit uygulama, hızlı karşılaştırma yapılabilir.

Eksiler:

  • Yanlış eşleşmeler, benzersizliği kaybetme.

**Olumlu örnek

#[derive(PartialEq, Eq)]'yi kullanır veya tüm iş mantığını dikkate alan kendi karşılaştırma sürümünü uygular, gerekli özellikleri güvence altına alır.

Artılar:

  • Koleksiyonlar düzgün çalışır, titiz davranış.

Eksiler:

  • Tasarım için dikkatli ve düşünceli bir yaklaşım gerektirir.