Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Diziler İçin IntoIterator

Özet

  • Diziler tüm sürümlerde IntoIterator uygular.
  • Metod çağrısı sözdizimi kullanıldığında (array.into_iter() gibi), IntoIterator::into_iter çağrıları Rust 2015 ve Rust 2018’de gizlenir. Bu yüzden array.into_iter(), eskiden olduğu gibi hâlâ (&array).into_iter() olarak çözülür.
  • array.into_iter(), Rust 2021’de doğrudan IntoIterator::into_iter çağrısı anlamına gelir.

Ayrıntılar

Rust 1.53’e kadar yalnızca dizilere verilen referanslar IntoIterator uyguluyordu. Yani &[1, 2, 3] ve &mut [1, 2, 3] üzerinde dönebilirdiniz, ama doğrudan [1, 2, 3] üzerinde dönemezdiniz.

for &oge in &[1, 2, 3] {} // Tamam :)

for oge in [1, 2, 3] {} // Hata :(

Bu, uzun süredir açık olan bir sorundu; ancak çözüm göründüğü kadar basit değildi. Yalnızca trait uygulamasını eklemek, mevcut kodu bozardı. array.into_iter() bugün zaten derlenebiliyor; çünkü metod çağrısı sözdiziminin çalışma biçimi nedeniyle örtük olarak (&array).into_iter() çağrılıyor. Trait uygulamasını eklemek bu anlamı değiştirirdi.

Normalde bu tür kırılmalar, yani bir trait uygulaması eklemek, “küçük” sayılır ve kabul edilebilir görülür. Ancak bu durumda bozulacak kod miktarı çok fazlaydı.

Birçok kez “yalnızca Rust 2021’de diziler için IntoIterator uygulasak” önerisi yapıldı. Ancak bu mümkün değildir. Sürümler karıştırılabildiği için, bir trait uygulamasının bir sürümde var olup diğerinde yok olması sağlanamaz.

Bunun yerine trait uygulaması tüm sürümlere eklendi; başlangıç noktası Rust 1.53.0 oldu. Ancak Rust 2021’e kadar kırılmayı önlemek için küçük bir geçici çözüm kullanıldı. Rust 2015 ve 2018 kodunda derleyici, array.into_iter() ifadesini, sanki bu trait uygulaması yokmuş gibi yine (&array).into_iter() olarak çözer. Bu davranış yalnızca .into_iter() metod çağrısı sözdizimi için geçerlidir. for e in [1, 2, 3], iter.zip([1, 2, 3]) veya IntoIterator::into_iter([1, 2, 3]) gibi diğer sözdizimlerini etkilemez. Bunlar tüm sürümlerde çalışmaya başlar.

Kırılmayı önlemek için böyle küçük bir geçici çözüme ihtiyaç duyulması ideal olmasa da, bu yaklaşım sürümler arasındaki farkı olabilecek en düşük seviyede tutar.

Taşıma

array_into_iter lint’i, Rust 2021’de anlamı değişecek bir into_iter() çağrısı olduğunda tetiklenir. Bu lint, 1.41 sürümünden beri tüm sürümlerde varsayılan uyarıdır; 1.55’te de çeşitli iyileştirmeler aldı. Kodunuz zaten uyarısızsa, büyük olasılıkla Rust 2021’e hazırdır.

Kodunuzu otomatik olarak Rust 2021 ile uyumlu hale getirmek veya zaten uyumlu olduğunu doğrulamak için şunu çalıştırabilirsiniz:

cargo fix --edition

Sürümler arasındaki fark küçük olduğu için Rust 2021’e taşıma da oldukça düzdür.

Diziler üzerindeki into_iter metod çağrılarında öğeler, referans olmaktan çıkıp sahip olunan değerlere dönüşür.

Örneğin:

fn main() {
  let dizi = [1u8, 2, 3];
  for oge in dizi.into_iter() {
    // oge, Rust 2015 ve Rust 2018'de `&u8` olur
    // oge, Rust 2021'de `u8` olur
  }
}

Rust 2021’e taşınırken önceki sürümlerdeki davranışı aynen korumanın en açık yolu, sahip olunan diziler üzerinde de referansla dolaşan iter() metodunu kullanmaktır:

fn main() {
  let dizi = [1u8, 2, 3];
  for oge in dizi.iter() { // <- Bu satır değişti
    // oge, tüm sürümlerde `&u8` olur
  }
}

İsteğe bağlı taşıma

Önceki bir sürümde tam nitelikli metod sözdizimi kullanıyorsanız (IntoIterator::into_iter(array) gibi), bunu metod çağrısı sözdizimine (array.into_iter()) dönüştürebilirsiniz.