type - swift switch
Costanti rapide: Struct o Enum (2)
Uso di Xcode 7.3.1 e Swift 2.2
Sebbene io sia d'accordo con Martin R, e la guida allo stile di Ray Wenderlich sottolinea che gli enum sono migliori in quasi tutti i casi di utilizzo, dato che si tratta di un puro spazio dei nomi, c'è un posto dove usare
enums
struct
trump.
Istruzioni switch
Cominciamo con la versione struct:
struct StaticVars {
static let someString = "someString"
}
switch "someString" {
case StaticVars.someString: print("Matched StaticVars.someString")
default: print("Didn't match StaticVars.someString")
}
Usando uno struct, questo
Matched StaticVars.someString
e stamperà
Matched StaticVars.someString
.
Ora consideriamo la versione enum senza caselle (cambiando solo la parola chiave
struct
in
enum
):
enum StaticVars {
static let someString = "someString"
}
switch "someString" {
case StaticVars.someString: print("Matched StaticVars.someString")
default: print("Didn't match StaticVars.someString")
}
Si noterà un errore di compilazione
case StaticVars.someString:
switch sul
case StaticVars.someString:
line.
L'errore è il
Enum case 'someString' not found in type 'String'
.
C'è una pseudo-soluzione alternativa convertendo la proprietà statica in una chiusura che restituisce invece il tipo.
Quindi lo cambieresti in questo modo:
enum StaticVars {
static let someString = { return "someString" }
}
switch "someString" {
case StaticVars.someString(): print("Matched StaticVars.someString")
default: print("Didn't match StaticVars.someString")
}
Nota la necessità di parentesi nell'istruzione case perché ora è una funzione.
Il rovescio della medaglia è che ora che l'abbiamo resa una funzione, viene eseguita ogni volta che viene invocata.
Quindi se è solo un semplice tipo primitivo come
String
o
Int
, questo non è poi così male.
È essenzialmente una proprietà calcolata.
Se è una costante che deve essere calcolata e vuoi calcolarla solo una volta, considera di calcolarla in una proprietà diversa e restituire quel valore già calcolato nella chiusura.
Potresti anche sovrascrivere l'inizializzatore predefinito con uno privato e quindi otterrai lo stesso tipo di bontà di errore del tempo di compilazione come con l'enum senza caseless.
struct StaticVars {
static let someString = "someString"
private init() {}
}
Ma con questo, vorresti mettere la dichiarazione della struttura nel suo file, perché se la dichiarassi nello stesso file di, diciamo, una classe View Controller, il file di quella classe sarebbe comunque in grado di creare un'istanza accidentale di un inutile istanza di
StaticVars
, ma al di fuori del file della classe funzionerebbe come previsto.
Ma è la tua chiamata.
Non sono sicuro di quale dei due sia meglio definire le costanti.
Una struttura o un enum.
Una struttura verrà copiata ogni volta che la uso o no?
A mio avviso, quando penso a una struttura con costanti di
static let
, non ha senso che verrà copiata continuamente.
Ma se non viene copiato, non importa cosa prendo?
Quali sono i vantaggi della scelta di una struttura o enum?
Francisco dice di usare Struct's.
Ray Wunderlich dice di usare Enum. Ma mi manca la giustificazione.
Ecco una breve risposta: le tue costanti devono essere uniche? Quindi usa un enum, che lo impone.
Vuoi usare diverse costanti diverse per contenere lo stesso valore (spesso utile per chiarezza)? Quindi utilizzare uno struct, che lo consente.