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

Panic Makrosunda Tutarlılık

Özet

  • panic!(..) artık println!() gibi her zaman format_args!(..) kullanır.
  • { karakterini {{ diye kaçırmadan panic!("{") yazmak artık kabul edilmez.
  • x bir dizgi sabiti değilse panic!(x) artık kabul edilmez.
    • Dizgi olmayan bir yükle panic üretmek için std::panic::panic_any(x) kullanın.
    • Ya da xin Display uygulamasını kullanmak için panic!("{}", x) yazın.
  • 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: {{}}").