Enum (sıralı tipler) Rust'ta C/C++'taki enum'lardan köklü bir şekilde farklıdır: ilişkilendirilmiş verileri saklama yeteneğine sahiptirler ve durum ve hataları modellemek için mükemmeldirler. Bunlar, tür güvenli finite-state machines oluşturmak, çeşitli Option/Result türlerini uygulamak ve "toplama türleri" modelleme desenini gerçekleştirmek için kullanılır. Tarihsel olarak, benzer yapılar, belirli varyantların kesin bir şekilde ayrıldığı varlıkların tanımı için fonksiyonel dillerde uygulanmıştır.
Sorun: tüm durum varyantlarını ifade edebilmek (her bir durumun işlenmesi zorunlu olmak üzere) ve yanlışlıkla bir dalı atlamanın imkânsız olması. Proje genelindeki hataları bu kadar ifadeli bir yapı olmadan türlendirmek zordur.
Çözüm: ilişkili veriler ve pattern matching ile enum, kontrol sağlar — her bir dal derleyici tarafından kontrol edilir, tamlık sağlanır. Ayrıca, Result ve Option için birçok yardımcı yöntem zaten uygulanmıştır.
Kod örneği:
enum NetworkState { Disconnected, Connecting(u32), // deneme numarası Connected(String), Error(String), } fn print_state(state: NetworkState) { match state { NetworkState::Disconnected => println!("Net: disconnected"), NetworkState::Connecting(count) => println!("Net: connecting (attempt {})", count), NetworkState::Connected(addr) => println!("Net: connected to {}", addr), NetworkState::Error(msg) => println!("Net error: {}", msg), } }
Anahtar özellikler:
Enum'un dallarını _ olmadan kısmen işlemek mümkün mü?
Derleyici, non-exhaustive enum için kapatılmamış durumları yasaklar, ancak _ kullanılırsa, işlenmemiş dallar "yutulmuş" olur. Klinik öneme sahip dallarda _ kullanmaktan kaçınmak gerekir, böylece gelecekteki değişiklikler gözden kaçmaz.
Pattern matching sırasında ilişkilendirilmiş değerler ne zaman referans alınır, ne zaman kopyalanır?
Pattern matching sırasında ilişkilendirilmiş veriler varsayılan olarak taşınır (move). Sadece görüntüleme istiyorsanız, referansları kullanın:
match &state { NetworkState::Connected(addr) => println!("by ref: {}", addr), _ => {} }
Aynı yapıda, isimleri çakışan iki enum kullanmak mümkün mü?
Mümkün, ancak varyant isimleri enum ön eki ile birlikte kullanılır. Bu, çakışmaları ortadan kaldırır ve kodu kendi kendini açıklayıcı hale getirir (örneğin, Status::Ok ve NetworkState::Ok).
_ kullanımı_ =>) aşırı kullanımıKodda Result<T, E> her zaman _ => ile catch-all içerir ve yeni hatalar (enum genişletildiğinde) gözden kaçıyor — sessiz hata kaybına neden oluyor.
Artıları:
Eksileri:
Tamlık eşleştirme (exhaustiveness matching) kullanılarak, her Enum varyantı açıkça işlenir veya belirli bir davranış olmayan bir dalda panic meydana gelir.
Artıları:
Eksileri: