Zpět

Swift – enum vs. struct

10 minut čtení 04. 02. 2021

Swift - enum nebo struct?

Při programování je často potřebné definovat konstanty – například dny, měsíce, možné akce, apod. V jazyce swift v této souvislosti kdekoho jako první napadne použít výčtový typ – enum.
V jistých situacích můžeme ale narazit na jistá omezení enumu, a je dobré znát další možnosti, jak se s tím vypořádat.

Enum

Jedná se o výčtový typ, který obsahuje konečné množství hodnot. Může být reprezentován libovolným základním datovým typem, obsahovat další asociované hodnoty, metody nebo počítané property. U jednotlivých hodnot lze počítat s implicitní konverzí na základní reprezentaci (pro Int inkrementálně, pro String totožně s názvem, atd.). Nebo ji uvést explicitně.
Jednoduchý výčtový typ může vypadat následovně:

Případná rozšíření mohou přidávat pouze nové metody nebo property, nikoliv nové hodnoty. Toto omezení ve výsledku znamená, že uvedený enum musí být vždy kompletní už ve své definici, což nemusí být vyhovující například v modulárních aplikacích. Následující kód obsahuje příklad jednoduchého rozšíření:

Enum se následně většinou používá v podmínkových výrazech, kdy nejčastěji vidíme konstrukci switch. Zde si ale ukážeme, jak lze sestavit podmínku s využitím základní reprezentace výčtového typu:

Jelikož má enum explicitně uveden základní datový typ, kterým je reprezentovaný, lze jej z proměnné takového typu i zkonstruovat. Toto může být výhodné například tehdy, kdy se enum vyskytuje v datovém modelu aplikace použitém pro reprezentaci dat ze serveru. Enum nabízí i implicitní konstruktor init?(rawValue:). Nepřehlédněte především fakt, že konstruktor je označen jako failable, viz následující ukázka:

Struct

Struct je heterogenní datová struktura, která se často používá k reprezentaci dat v aplikaci (modely). Jejich použití tímto ovšem není limitováno a lze je využít, mimo jiné, i jako alternativu k výčtovému typu. Pokud tedy nahradíme dříve uvedený enum, struktura může vypadat následovně:

V případě podmínky s využitím základní reprezentace výčtového typu vidíme, že kód po změně na strukturu zůstal naprosto stejný. Pokud se v aplikaci vyskytují pouze obdobné konstrukce stavějící na základní reprezentaci enumu (například pro konstanty), může být přechod na strukturu se statickými konstantami vskutku přínosný, zejména v modulárním kódu.

Přechod na strukturu se statickými konstantami s sebou ovšem nese i nevýhody. U výčtového typu jsme byli schopni jej zkonstruovat přímo z textové hodnoty, což v případě struktury není implicitně možné. Nabízí se samozřejmě možnost obdobné chování doimplementovat ručně (viz ukázka kódu níže), ovšem i zde existuje jistá omezení. Při použití statických konstant je totiž nutné mít na paměti to, že statické proměnné se inicializují pomocí principu lazy loading, čili až v době prvního přístupu. V uvedeném příkladu to tedy znamená, že pole registeredCases se naplní všemi hodnotami až ve chvíli, kdy se ke všem těmto hodnotám poprvé přistoupí.

Závěr

Ukázali jsme si jednoduché použití výčtového typu v jazyce swift, který se používá zejména pro definování konstant nebo konečné sady hodnot. Někdy je ale právě toto omezení konečnosti pro naše použití nevyhovující, například v modulárních aplikacích. Lze proto výčtový typ nahradit strukturou se statickými konstantami, což usnadňuje vyšší modularizaci kódu, ovšem s určitými omezeními. Konečné rozhodnutí na použití těchto přístupů vždy závisí na konkrétní situaci.

Pokud Vám je swift blízký, je veškerý kód dostupný v github repozitáři zde.

Nabíráme, přidej se k nám!

Kariéra v B2A