Sidebar

Enum-klasser giver anledning til mange kontroverser i Android-verdenen af forskellige årsager, men de bliver stadig brugt af erfarne udviklere dag efter dag. Hvorfor er det sådan?

(Heads up: Selv om syntaksen i koden her vil være i Kotlin, gælder alle oplysningerne her også for Java enum-klasser)

Hvad er en Enum-klasse?

Simpelt sagt er en Enum en særlig klassetype, der indeholder en liste af konstanter. Den mest almindelige anvendelse af dette er at repræsentere forskellige typer af et bestemt objekt, eller når en variabel kun kan være en af et bestemt sæt værdier.

enum class Direction { NORTH, SOUTH, EAST, WEST}

Konstanterne i et enum kræver ikke nødvendigvis en værdi. Uden en værdi kan de bruges i validering gennem ifs- og switch-angivelser.

val directionToTreasure = Direction.NORTHwhen(directionToTreasure) { Direction.NORTH -> indicateNorth() Direction.SOUTH -> indicateSouth() Direction.EAST -> indicateEast() Direction.WEST -> indicateWest()}

Men det er nok ikke den bedste måde at håndtere disse angivelsesfunktioner på, men du får idéen. Det bliver i hvert fald meget sjovt

Deres brug kan dog udvides til at omfatte værdier, der er knyttet til hver konstant.

enum class Color(val rgb: Int) { RED(0xFF0000) GREEN(0x00FF00) BLUE(0x0000FF)}

Når du bruger enum-klasser på denne måde, kan du få deres værdi på følgende måde:

val shirtColour = Color.BLUEval color: Int = shirtColour.rgb

Hvad kan en enum ellers gøre?

For at sige det kort og godt, en helvedes masse

For det første kan enum i stedet for konstanter implementeres som anonyme klasser med deres egne metoder og overskrivning af basismetoder.

enum class ProtocolState yadayada {}

De kan også implementere interfaces på en lignende måde

enum class IntArithmetics yadayada {}

Endeligt har enum to konstanter, som giver dig nogle ret nyttige værdier.

Faktisk kan du takket være brugen af disse konstanter også bekvemt mappe mellem enum- og String/Int-typer.

Enum -> Int

yourEnum.ordinal

Int -> Enum

EnumType.values()

String -> Enum

EnumType.valueOf(yourString)

Enum -> String

yourEnum.name

Kredit til denne fyr på StackOverflow for at dele denne mapping

Hvad er formålet med Enum-klasser?

Jeg forstår dig, det er ikke det mest ligetil, men jeg skal nok oplyse dig om det.

For det meste bruges enum-klasser til at producere mere læsbar kode. Når du har et objekt, der kan have flere forskellige typer, er det meget mere kortfattet at identificere dem med en læsbar værdi end et vilkårligt heltal.

// 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()}

Et andet nyttigt formål med Enums er, når du har data, der kommer ind som en streng, men du skal i sidste ende mappe det til en int-værdi, som når dit API giver dit objekts type, men du skal sende det ind i en RecyclerView Adapter, der kræver en Int for View-typer. Personligt brugte jeg denne metode i min enum-klasse for at få det til at ske.

@JvmStaticfun getType(type: String): BlockType? = when(type) { "hero" -> ContentHero "products" -> ContentProductList else -> null }

Hvorfor du ikke bør bruge Enum-klasser

Jeg vil vædde med, at du nu tænker “Vent lige et øjeblik. Du har fortalt mig alt om, hvordan man bruger Enums, og nu vil du bare fortælle mig, at jeg ikke skal bruge dem?”. Hør på mig.

Simpelt sagt, Enums er dyre, makker! Jeg ved godt, at mobiltelefoner bliver bedre for hver dag, men for det første er der stadig for mange mennesker derude med mindre kraftfulde telefoner, og for det andet bruger den måde, vi laver apps på, og de biblioteker, vi bruger, også mere hukommelse.

Dette er en gammel nyhed. Enums ville være et hukommelsesproblem for telefoner, der kører med Dalvik, men det er stort set blevet afskaffet i stedet for ART (Android Runtime Machine). Sammen med det faktum, at selv folk i fattigere lande har ret kraftige telefoner, og at Proguard nu kan optimere koden bedre end nogensinde før, kan man roligt sige, at Enums ikke længere giver et problem med hensyn til ydeevne.

Der er stadig et par alternativer, du kan bruge, som kan opnå lignende resultater som en Enum-klasse.

Constants

Constants er også superkonkrete. De holder en enkelt værdi og giver den et navn. De er også ekstremt lette.

*Def

*Def-annotationen er også fantastisk, hvis du har en variabel, der kun tager imod bestemte værdier.

@IntDef({RED, GREEN, BLUE})

Hvorfor vælger du stadig Enums frem for disse alternativer?

Hvor Enum skinner meget mere end sine funktionelle søskende er udtømmelighed. Når du bruger Kotlin, kan du bruge en switch-anvisning som denne

val foo = when(someEnum) {}

Og når du gør det, er du tvunget til at håndtere et tilfælde for hver konstant i dit enum, ellers vil din kode ikke kompileres. Med konstanter og *def-annotationer er det bedste, du får givet, lint-advarsler. Enums fører simpelthen til mere sikker kode.

(Credits to u/-manabreak from Reddit for this)

Så længe din brug af enums fører til mere kortfattet kode for din applikation og især i Kotlins tilfælde til bedre case-sikkerhed, kan du med alle midler enumerere efter hjertens lyst.

Skriv en kommentar