Ce face enum class
O clasă enum are un set fix de valori, scrise în corp: enum class Anotimp { PRIMAVARA, VARA, TOAMNA, IARNA }. O variabilă de tipul Anotimp poate avea doar una dintre aceste valori, nu un text oarecare, deci greșelile de scriere sunt prinse la compilare.
Fiecare valoare are name (numele ca text) și ordinal (poziția, de la 0). Anotimp.entries (Kotlin 1.9+) dă lista tuturor valorilor, iar Anotimp.valueOf("VARA") găsește valoarea după nume (aruncă IllegalArgumentException dacă numele nu există). Valorile pot avea proprietăți (din constructor) și metode; după ultima valoare se pune ; înaintea membrilor.
when pe o valoare enum este exhaustiv: dacă tratezi toate valorile, nu ai nevoie de else, iar dacă adaugi o valoare nouă, compilatorul îți arată unde ai uitat-o.
Exemple
Exemplul 1: Enum simplu, entries și when
when tratează toate cele patru valori, deci nu are else. entries parcurge valorile în ordinea declarării.
enum class Anotimp { PRIMAVARA, VARA, TOAMNA, IARNA }
fun activitate(a: Anotimp) = when (a) {
Anotimp.PRIMAVARA -> "plantăm flori"
Anotimp.VARA -> "mergem la mare"
Anotimp.TOAMNA -> "culegem struguri"
Anotimp.IARNA -> "facem om de zăpadă"
}
fun main() {
for (a in Anotimp.entries) {
println("${a.ordinal} ${a.name}: ${activitate(a)}")
}
val ales = Anotimp.valueOf("VARA")
println("Ales: $ales")
}
Rezultat
0 PRIMAVARA: plantăm flori
1 VARA: mergem la mare
2 TOAMNA: culegem struguri
3 IARNA: facem om de zăpadă
Ales: VARA
Exemplul 2: Enum cu proprietăți și metode
Fiecare stare a comenzii are un text și un număr de zile. Metoda urmatoarea folosește ordinal și entries.
enum class StareComanda(val text: String, val zile: Int) {
PLASATA("Comandă plasată", 0),
PREGATITA("În pregătire", 1),
EXPEDIATA("Predată curierului", 2),
LIVRATA("Livrată", 4);
fun urmatoarea(): StareComanda? = entries.getOrNull(ordinal + 1)
}
fun main() {
var stare: StareComanda? = StareComanda.PLASATA
while (stare != null) {
println("Ziua ${stare.zile}: ${stare.text}")
stare = stare.urmatoarea()
}
}
Rezultat
Ziua 0: Comandă plasată
Ziua 1: În pregătire
Ziua 2: Predată curierului
Ziua 4: Livrată
Exemplul 3: valueOf cu nume greșit și comparare
Valorile enum se compară după ordinea declarării. valueOf cu un nume inexistent aruncă excepție; entries.find este varianta sigură.
enum class Marime { S, M, L, XL }
fun main() {
println("M < XL? ${Marime.M < Marime.XL}")
println("Cea mai mare: ${Marime.entries.max()}")
try {
Marime.valueOf("XXL")
} catch (e: IllegalArgumentException) {
println("Eroare: ${e.message}")
}
println(Marime.entries.find { it.name == "XXL" } ?: "mărime necunoscută")
}
Rezultat
M < XL? true
Cea mai mare: XL
Eroare: No enum constant Marime.XXL
mărime necunoscută
Greșeli frecvente
- Uitarea lui
;după ultima valoare când enum-ul are metode: eroare de sintaxă. - Folosirea lui
values()în cod nou: funcționează, dar creează un tablou nou la fiecare apel. Din Kotlin 1.9 foloseșteentries. - Salvarea lui
ordinalîn baza de date: dacă reordonezi sau inserezi valori, numerele se schimbă. Salveazănamesau un cod propriu.
Comenzi înrudite
when: Alege o ramură după valoarea unei expresii sau după prima condiție adevărată; înlocuiește switch din alte limbaje.sealed class și sealed interface: sealed declară o ierarhie închisă: toate subtipurile sunt cunoscute la compilare, deci when le poate verifica pe toate fără else.class: class declară o clasă: un tip nou care grupează date (proprietăți) și comportament (metode).data class: data class este o clasă pentru date: primește automat toString, equals, hashCode, copy și componentN.