Enum classes doen om een aantal redenen veel stof opwaaien in de Android wereld, maar ze blijken nog steeds dag in dag uit gebruikt te worden door ervaren ontwikkelaars. Waarom is dit zo?
(Heads up: terwijl de syntaxis van de code hier in Kotlin zal zijn, geldt alle informatie hier ook voor Java enum classes)
Wat is een Enum klasse?
Vereenvoudig gezegd, een Enum is een speciaal class type dat een lijst van constanten bevat. Het meest gebruikelijke gebruik hiervan is om verschillende typen van een bepaald object weer te geven, of wanneer een variabele slechts een van een bepaalde reeks waarden kan zijn.
enum class Direction { NORTH, SOUTH, EAST, WEST}
De constanten van een enum behoeven niet noodzakelijkerwijs een waarde te hebben. Zonder een waarde kunnen ze worden gebruikt in validatie door middel van ifs en switch statements.
val directionToTreasure = Direction.NORTHwhen(directionToTreasure) { Direction.NORTH -> indicateNorth() Direction.SOUTH -> indicateSouth() Direction.EAST -> indicateEast() Direction.WEST -> indicateWest()}
Waarschijnlijk niet de beste manier om met deze aanduidingsfuncties om te gaan, maar je snapt het idee. Het wordt in ieder geval erg leuk
Hun gebruik kan echter worden uitgebreid met waarden die aan elke constante zijn gekoppeld.
enum class Color(val rgb: Int) { RED(0xFF0000) GREEN(0x00FF00) BLUE(0x0000FF)}
Wanneer u enumklassen op deze manier gebruikt, kunt u hun waarde als volgt krijgen:
val shirtColour = Color.BLUEval color: Int = shirtColour.rgb
Wat kan een Enum nog meer?
Om het in een notendop te zeggen, verdomd veel
Ten eerste, in plaats van constanten, kunnen enums worden geïmplementeerd anonieme klassen met hun eigen methoden en het overschrijven van basismethoden.
enum class ProtocolState yadayada {}
Ze kunnen ook interfaces implementeren op een vergelijkbare manier
enum class IntArithmetics yadayada {}
Ten slotte, enum heeft twee constanten die u voorzien van een aantal vrij nuttige waarden.
val name: String // The name of the constantval ordinal: Int // The position of the constant in the list of valuesif (shirtColour.name == "BLUE") { // Do some blue stuff}
Dankzij het gebruik van deze constanten, kunt u ook handig mappen tussen enum en String/Int types.
Enum -> Int
yourEnum.ordinal
Int -> Enum
EnumType.values()
String -> Enum
EnumType.valueOf(yourString)
Enum -> String
yourEnum.name
Credits aan deze kerel op StackOverflow voor het delen van deze mapping
Wat is het doel van Enum klassen?
Ik snap je, het is niet de meest eenvoudige zaak, maar ik zal je inlichten.
Voor het grootste deel worden enum klassen gebruikt om meer leesbare code te produceren. Wanneer je een object hebt dat meerdere verschillende types kan hebben, is het veel beknopter om ze te identificeren met een leesbare waarde dan een willekeurig geheel getal.
// Bad codewhen(direction) { 0 -> goNorth() 1 -> goSouth() 2 -> goEast() 3 -> goWest()}// Good codewhen(direction) { Direction.NORTH -> goNorth() Direction.SOUTH -> goSouth() Direction.EAST -> goEast() Direction.WEST -> goWest()}
Een ander nuttig doel van Enums is wanneer je gegevens hebt die binnenkomen als een string, maar die je uiteindelijk moet mappen naar een int waarde, zoals wanneer je API het type van je object geeft, maar je het moet doorgeven aan een RecyclerView Adapter die een Int vereist voor View types. Ik heb zelf deze methode in mijn enum klasse gebruikt om dat voor elkaar te krijgen.
@JvmStaticfun getType(type: String): BlockType? = when(type) { "hero" -> ContentHero "products" -> ContentProductList else -> null }
Waarom je geen enum klassen moet gebruiken
Ik durf te wedden dat je nu denkt “Wacht eens even. Je hebt me verteld hoe ik Enums moet gebruiken en nu ga je me vertellen dat ik ze niet moet gebruiken?”. Luister naar me, maat.
Simpel gezegd, Enums zijn duur, maat! Ik weet dat mobiele telefoons met de dag beter worden, maar ten eerste zijn er nog steeds te veel mensen met minder krachtige telefoons en ten tweede gebruiken de manier waarop we apps maken en de bibliotheken die we gebruiken ook meer geheugen.
Dit is oud nieuws. Enums zouden een geheugenprobleem zijn voor telefoons die met Dalvik werken, maar dat is in principe afgeschaft in plaats van de ART (Android Runtime Machine). Gevoegd bij het feit dat zelfs mensen in armere landen redelijk krachtige telefoons hebben, en dat Proguard code nu beter dan ooit kan optimaliseren, is het veilig om te zeggen dat Enums geen probleem meer veroorzaken in performance.
Er zijn nog een paar alternatieven die je kunt gebruiken die vergelijkbare resultaten kunnen bereiken als een Enum class.
Constants
Constants zijn ook super beknopt. Ze bevatten een enkele waarde en geven die een naam. Ze zijn ook extreem licht.
*Def
De *Def annotatie is ook geweldig als je een variabele hebt die alleen bepaalde waarden aanneemt.
@IntDef({RED, GREEN, BLUE})
Waarom nog steeds Enums boven deze alternatieven kiezen?
Waar de enum veel meer schittert dan zijn functionele broers en zussen is uitputtendheid. In combinatie met Kotlin kun je een switch statement als dit gebruiken
val foo = when(someEnum) {}
En als je dat doet, ben je gedwongen om voor elke constante in je enum een case te behandelen, anders zal je code niet compileren. Met constanten en *def annotaties, het beste wat je krijgt zijn lint waarschuwingen. Enums leiden gewoon tot veiligere code.
(Credits naar u/-manabreak van Reddit voor dit)
Dus zolang je gebruik van enums leidt tot beknoptere code voor je applicatie en vooral in Kotlin’s geval, betere case safety, by all means, enumerate to your heart’s content.