Diziler İçin IntoIterator
Özet
- Diziler tüm sürümlerde
IntoIteratoruygular. - 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üzdenarray.into_iter(), eskiden olduğu gibi hâlâ(&array).into_iter()olarak çözülür. array.into_iter(), Rust 2021’de doğrudanIntoIterator::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.