Amikor olyan adatokat modellezel, amelyek csak meghatározott számú lehetséges állapotot vehetnek fel, például a hét napjait, az égtájakat vagy egy irányító gombjait, az olyan alaptípusok, mint az Int vagy a String, komoly hátrányokkal járnak.
Egész számok vagy stringek használatakor a kódodnak folyamatosan ellenőriznie kell az érvénytelen értékeket (például egy 999 állapotkódot vagy egy "leftt" elgépelést), és az olvasók számára sem könnyű kitalálni, mit jelentenek a számok.
A Swift ezt a problémát az Enumerations (amit gyakran csak enumnak neveznek) segítségével oldja meg. Az enum egy közös típust definiál egy összetartozó, névvel ellátott értékekből álló csoport számára. Mivel a fordító előre ismeri az összes lehetséges esetet, fordításkor ellenőrizni tudja a kódod helyességét és teljességét. Az enumoknak emellett lehetnek metódusaik, kezdőértékeik és számított tulajdonságaik.
Az enumot az enum kulcsszóval definiálod, utána a típusnév következik, az eseteket pedig kapcsos zárójelben ({}) sorolod fel.
A Swift konvenciója szerint a típusnév UpperCamelCase stílusban, az egyes esetek pedig lowerCamelCase stílusban íródnak:
enum NESButton {
case up
case down
case left
case right
case a
case b
case select
case start
}
Több esetet egyetlen sorban is definiálhatsz, vesszőkkel elválasztva:
enum NESButton {
case up, down, left, right, a, b, select, start
}
Egy enum-esetre úgy hivatkozol, hogy leírod az enum típusnevét, egy pontot (.) és az eset nevét. Ha a típus ismert, vagy a fordító ki tudja következtetni, elhagyhatod a típusnevet, és a rövidebb pont szintaxist használhatod:
var lastPressed = NESButton.up
// Swift infers the type, so you can omit the type name:
lastPressed = .down
let konamiCode: [NESButton] = [.up, .up, .down, .down, .left, .right, .left, .right, .b, .a]
Az enumok ugyanúgy definiálhatnak metódusokat és saját kezdőértékeket, mint az osztályok és a struktúrák. Egy enum metódusán belül a self az aktuális esetértékre utal:
enum Coin {
case heads
case tails
init(_ value: Int) {
if value.isMultiple(of: 2) {
self = .heads
} else {
self = .tails
}
}
func flip() -> Coin {
switch self {
case .heads: return .tails
case .tails: return .heads
}
}
}
let tails = Coin(13) // .tails
let heads = Coin(0) // .heads
let flipped = heads.flip() // .tails
Az enum esetei előre kitölthetők alapértelmezett értékekkel, ezeket nyers értékeknek hívjuk.
Egy enumban minden nyers értéknek ugyanolyan típusúnak kell lennie (például Int, String vagy Character):
enum NESButton: Character {
case up = "⬆️"
case down = "⬇️"
case left = "⬅️"
case right = "➡️"
case a = "🅰️"
case b = "🅱️"
case select = "✅"
case start = "🚦"
}
print(NESButton.left.rawValue) // Prints "⬅️"
Egy enumot nyers értékéből az init(rawValue:) segítségével hozhatsz létre. Mivel előfordulhat, hogy érvénytelen nyers értéket adsz meg, ez a kezdőérték opcionális értéket ad vissza:
let upButton = NESButton(rawValue: "⬆️") // Optional(NESButton.up)
let invalid = NESButton(rawValue: "🙄") // nil
A Swift automatikusan tud nyers értékeket hozzárendelni String és Int típusú enumokhoz:
String típusú enumoknál minden eset nyers értéke alapértelmezés szerint maga az eset neve.Int típusú enumoknál a nyers értékek 0-tól indulnak, és 1-gyel nőnek, hacsak másképp nem adod meg.enum Planet: Int {
case mercury = 1, venus, earth, mars
}
print(Planet.earth.rawValue) // Prints 3
Ebben a feladatban naplósorokkal fogsz dolgozni.
Minden naplósor egy "[<LVL>]: <MESSAGE>" formátumú string.
Ezek a különböző naplózási szintek:
TRC (trace)DBG (debug)INF (info)WRN (warning)ERR (error)FTL (fatal)Három részfeladatod van, amelyeket mind teljesítened kell a szükséges funkció biztosításához.
Definiálj egy LogLevel felsorolást, amelynek hat esete megfelel a fenti naplózási szinteknek, valamint egy ismeretlen eset a hiányzó vagy nem szabványos naplózási szintekhez.
tracedebuginfowarningerrorfatalunknownEzután valósítsd meg a LogLevel kezdőértékét, hogy értelmezze egy naplósor naplózási szintjét:
LogLevel("[INF]: File deleted")
// Returns LogLevel.info
LogLevel("Something went wrong!")
// Returns LogLevel.unknown
Egy naplósor naplózási szintje meglehetősen hosszadalmas.
Hogy csökkentsük a naplósorok tárolásához szükséges lemezterületet, kifejlesztettek egy rövid formátumot: "<ENCODED_LEVEL>:<MESSAGE>".
A kódolt naplózási szint egyszerű megfeleltetés a naplózási szint és egy szám között:
trace - 0
debug - 1
info - 4
warning - 5
error - 6
fatal - 7
unknown - 42
Valósítsd meg a shortFormat(message: String) -> String metódust, amely String-ként kiírja a rövidített naplósor-formátumot:
let overflow = LogLevel.error
overflow.shortFormat(message: "Stack overflow")
// Returns "6:Stack overflow"
Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) Swift nyelvet 35 fogalom116 feladat segítségével, valódi emberi mentorálással, mindez ingyen.