Panic Makrosunda Tutarlılık
Özet
panic!(..)artıkprintln!()gibi her zamanformat_args!(..)kullanır.{karakterini{{diye kaçırmadanpanic!("{")yazmak artık kabul edilmez.xbir dizgi sabiti değilsepanic!(x)artık kabul edilmez.- Dizgi olmayan bir yükle panic üretmek için
std::panic::panic_any(x)kullanın. - Ya da
xinDisplayuygulamasını kullanmak içinpanic!("{}", x)yazın.
- Dizgi olmayan bir yükle panic üretmek için
- Aynı kural
assert!(expr, ..)için de geçerlidir.
Ayrıntılar
panic!() makrosu, Rust’ın en iyi bilinen makrolarından biridir. Ancak
bazı ince sürprizleri vardır
ve geriye dönük uyumluluk nedeniyle bunları öylece değiştiremeyiz.
// Rust 2018
panic!("{}", 1); // Tamam, "1" ile panic üretir
panic!("{}"); // Tamam, "{}" ile panic üretir
panic!() makrosu yalnızca birden fazla argümanla çağrıldığında dizgi
biçimlendirmesi kullanır. Tek argümanla çağrıldığında ise o argümana bile bakmaz.
// Rust 2018
let a = "{";
println!(a); // Hata: İlk argüman bir biçim dizgisi sabiti olmalı
panic!(a); // Tamam: panic makrosu bunu umursamaz
Hatta panic!(123) gibi dizgi olmayan değerleri bile kabul eder. Bu kullanım
pek yaygın ya da yararlı değildir; çünkü şaşırtıcı derecede faydasız bir mesaj
üretir: panicked at 'Box<Any>'.
Bu, özellikle örtük biçim argümanları
kararlı hale geldiğinde sorun olacaktır. Bu özellik
println!("hello {name}") ifadesini println!("hello {}", name) için bir
kısayola dönüştürür. Ancak panic!("hello {name}") beklendiği gibi çalışmaz;
çünkü panic!() tek argümanı biçim dizgisi olarak işlemez.
Bu kafa karıştırıcı durumu önlemek için Rust 2021 daha tutarlı bir panic!()
makrosu getirir. Yeni panic!() makrosu artık tek argüman olarak rastgele
ifadeleri kabul etmez. println!() gibi ilk argümanı her zaman biçim dizgisi
olarak işler. panic!() artık keyfi yükleri kabul etmeyeceği için,
panic_any(),
biçimlenmiş dizgi dışındaki bir değerle panic üretmenin tek yolu olur.
// Rust 2021
panic!("{}", 1); // Tamam, "1" ile panic üretir
panic!("{}"); // Hata, eksik argüman
panic!(a); // Hata, bir dizgi sabiti olmalı
Ayrıca Rust 2021’de core::panic!() ile std::panic!() birebir aynı olur.
Bugün bu ikisi arasında tarihsel farklar vardır ve #![no_std] açılıp
kapatılırken bu farklar fark edilebilir.
Taşıma
non_fmt_panics lint’i, Rust 2021’de hataya dönüşecek kullanımdan kaldırılmış
bir panic çağrısı bulunduğunda tetiklenir. Bu lint, 1.50 sürümünden beri
tüm sürümlerde varsayılan uyarıdır; sonraki sürümlerde de birkaç iyileştirme
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 ya da zaten uyumlu olduğunu doğrulamak için şunu çalıştırabilirsiniz:
cargo fix --edition
Elle taşıma yapmayı seçerseniz ya da buna ihtiyaç duyarsanız, tüm panic
çağrılarını ya println! ile aynı biçimlendirmeyi kullanacak şekilde ya da
dizgi olmayan veriler için std::panic::panic_any kullanacak şekilde
güncellemeniz gerekir.
Örneğin panic!(BenimYapi) kullanıyorsanız, bunu std::panic::panic_any
kullanımına dönüştürmeniz gerekir. Bunun makro değil fonksiyon olduğuna dikkat edin:
std::panic::panic_any(BenimYapi).
Panic mesajında süslü parantezler bulunup argüman sayısı yanlışsa
(panic!("Bazi susluler: {}") gibi), dizgi sabitiyle panic üretmek için ya
println! ile aynı sözdizimini kullanabilirsiniz:
panic!("{}", "Bazi susluler: {}")
ya da süslü parantezleri kaçırabilirsiniz:
panic!("Bazi susluler: {{}}").