Bir Enum Tanımlamak
enum, değerleri sabit bir isimlendirilmiş variant kümesi olan bir tip tanımlar:
enum Status {
ready,
failed,
}
Artık Status, tam olarak iki değeri olan bir tiptir: Status.ready ve Status.failed. Başka hiçbir şey bir Status olamaz.
Gramer bilinçli olarak küçüktür:
enum Name {bildirimi açar.- Her satır virgülle ayrılmış bir variant adı listeler.
}onu kapatır.
Payload yok, discriminator değer yok, türetilmiş metot yok — bu, enum'u Zero'da "küçük sum type" olarak tutan şeydir.
Bir Enum Kullanmak
Bir variant'ı enum tipiyle nitelendirerek adlandırırsınız:
let state: Status = Status.ready
: Status annotation'ı sağ taraf tipi sabitlediği için opsiyoneldir; çoğu durumda şöyle yazabilirsiniz:
let state = Status.ready
ve compiler tipi Status olarak çıkarır.
Enum Değerlerini Karşılaştırmak
İki enum değeri aynı variant olduklarında eşittir:
if state == Status.ready {
check world.out.write("ready\n")
} else {
check world.out.write("not ready\n")
}
Bu, bir enum üzerinde dallanmanın en basit yoludur. Exhaustive analiz için — her variant'ı explicit ele almak için — match'e başvurun:
match state {
.ready => { check world.out.write("ready\n") }
.failed => { check world.out.write("failed\n") }
}
match'in if/else if'e göre avantajları, sonradan üçüncü bir variant eklediğinizde ortaya çıkar. Compiler yeni case'i kaçıran her match'i size bildirir; bir if/else zinciri ise sessizce varsayılan dalına geçer.
Choice ve match match'i daha ayrıntılı işliyor. Hem enum hem de choice için çalışır.
İşlenmiş Bir Örnek
Resmi Zero örneği enum ve choice'ı aynı dosyada yan yana koyar:
Status bu snippet'te bir şey yapmıyor — kontrast göstermek için orada. Bir choice variant'ı match edildiğinde bir payload bağlar (value, message); bir enum variant'ı ise bağlanacak hiçbir şey olmadığı için hiçbir şey bağlamaz.
Enum vs. Choice: Hızlı Bir Karar Ağacı
Kısa bir kural:
- Variant'lar yalnızca etiket ise →
enum. - Variant'lar veri taşımak zorundaysa →
choice.
Lifecycle state'leri modelliyorsanız ve sonunda "failed" state'ine bir hata mesajı iliştirmeniz gerekirse, tipi enum'dan choice'a geçirin. Variant'lar her biri bir payload tipi alır ve aşağıdaki match kolları o payload için bir bağlama kazanır. Compiler size adım adım rehberlik eden bir refactor.
Somut olarak:
// Önce — enum, payload yok
enum Status {
ready,
failed,
}
// Sonra — her variant'ında payload olan choice
choice Status {
ready: Void,
failed: String,
}
Payload'ı Void olan variant'lar choice formunda sadece etikettir. Aynı mantıksal state'ler için enum veya choice kullanabilirsiniz; veri iliştirme ihtiyacınız gerçekten yoksa enum'u seçin.
Kullanım Alanları
enum'un doğru cevap olduğu bazı günlük örnekler:
- Metadata'sız lifecycle.
Loading,Ready,Empty— saf state'ler, payload yok. - Modlar. Bir dosya açma modu için
Read,Write,Append. - Yön.
North,South,East,West. - Log seviyesi.
Trace,Debug,Info,Warn,Error. (Sonradan bir mesaj eklemek isteyebilirsiniz; o noktadachoice'a geçersiniz.) - Haftanın günü. Kanonik bir örnek.
Aksi takdirde sihirli bir integer sabitine (0 = pending, 1 = active, 2 = done) başvuracağınız her yerde, bir enum neredeyse her zaman daha nettir.
Stil Notları
- Küçük harfli variant adları, dilin geri kalanındaki identifier'lar için Zero'nun stiline uyar.
- Son variant'tan sonra trailing virgül sorunsuzdur (ve diff dostu olduğu için önerilir — yeni bir variant eklemek önceki satırı bozmaz).
- Enum listelerini küçük tutun. Bir düzine variant'ınız varsa ve çoğu payload istiyorsa, daha büyük bir
enumyerine birchoice'a — ya da bir yeniden tasarıma — bakıyor olabilirsiniz.
Sırada: Choice ve Match
Doğal sonraki adım, daha zengin kuzen: choice ve match — Zero'nun tagged-union tipi ve onunla birlikte gelen pattern-matching yapısı.
Sıkça Sorulan Sorular
Zero'da enum nedir?
Bir enum, değerleri sabit bir isimlendirilmiş variant kümesinden biri olan bir tip tanımlar — payload taşımayan etiketler. Örnek: enum Status { ready, failed }. Status tipindeki bir değer tam olarak Status.ready veya Status.failed'dir; compiler bunu zorlar.
enum, choice'tan nasıl farklıdır?
Bir enum'un variant'ları yalnızca etiketlerdir — veri taşımazlar. Bir choice ise bir tagged union'dur — her variant choice Result { ok: i32, err: String } gibi ilgili bir payload tipine sahiptir. Case'leri yalnızca isim üzerinden ayırmanız gerektiğinde enum kullanın; her case ekstra bilgi taşıdığında choice kullanın.
Bir değerin hangi enum variant'ına sahip olduğunu nasıl kontrol ederim?
Değeri variant ile karşılaştırın: if status == Status.ready { ... }. Tüm variant'lar üzerinde exhaustive dallanma için match kullanın — compiler bir variant'ı kaçırırsanız uyarır; bu, değer bir sum type olduğunda match'i if/else if zincirlerine tercih etmenin ana sebebidir.
Zero'da enum variant'ları ilişkili değer taşıyabilir mi?
Hayır — bu choice'ın görevidir. enum, bilinçli olarak minimal sum type'dır: her variant yalnızca bir etikettir. Variant'lardan birine bir i32 veya String iliştirmeniz gerekiyorsa, enum'u aşmışsınızdır ve bir choice istiyorsunuzdur.
Zero'da enum'u ne zaman kullanmalıyım?
Bir değer küçük, isimlendirilmiş bir state kümesinden tam olarak biri olmak zorundaysa ve bu state'ler ekstra veri taşımıyorsa enum kullanın. Örnekler: haftanın günü, trafik ışığı rengi, metadata'sız bir lifecycle state, bir logging seviyesi. Variant'lardan birine veri iliştirmek istediğinizi fark ederseniz choice'a geçin.