Enums, die gespeicherte Instanzeigenschaften nicht zulassen, sind eine Entwurfsauswahl. Wenn Enumeration mit gespeicherten Instanzeigenschaften verwendet wird, wird es wie eine Struktur (mit enum superpowers), aber nur vom Typ Perspektive werden Enums nun wie Typmultiplizierer. Grundsätzlich betrachten
enum Set1 {
case a
case b
case c
}
enum Times {
case x
case y
var k: Set1
}
Was bedeutet eigentlich, dass Enum Times
erlaubt uns, jede Kombination von Elementen aus Set1
und Set2
mit in 6 verschiedene Fälle führt, aber warten wir eigentlich wissen, dies ist ein Ziel eines Tupels Typ wie (Set1, Set2)
, wo Times
als
typealias Times = (Set1, Set2)
erklärt werden, hoffe ich, dies als eine vernünftige Begründung dient nicht dem ersteren Fall erlaubt.
aber sagte, dass rasche Aufzählungen ermöglichen es uns, mit jedem Fall ein beliebiges n-Tupel Assoziieren, so dass uns zu erklären, was als diskriminierte Union in der funktionalen Programmierung bekannt ist. Nennen Sie es eine gespeicherte Eigenschaft, die an Fall angehängt wird, wenn Sie mögen. Aus Typensicht wirkt es jetzt als Typaddierer.
enum Add {
case lhs(Set1)
case rhs(Set2)
}
Wir haben jetzt 5 verschiedene Fälle. Wenn wir jetzt speichern 2-Tupel:
enum AddTimes {
case lhs(Set1, Set2)
case rhs(Set3, Set4)
}
wir jetzt haben grundsätzlich Summe der Multiplikation (Set1 * Set2 + Set3 * Set4). Dies ist ein sehr leistungsfähiges Werkzeug, wenn es um Mustererkennung geht.
aber gibt es einige echte Fälle, wenn Sie tatsächlich die Form der gespeicherten Eigenschaft in enum emulieren wollen. Bedenken Sie:
public enum Service {
case registerNewUser(username: String, password: String, language: String)
case login(username: String, password: String, deviceTokenº: String?)
case logout(sessionToken: String)
case sendForgotPassword(email: String)
}
ist eine deklarative Weise REST-Endpunkte definieren (in Rahmen wie Moya) Wenn Sie eine Anforderung feuern wollen Sie so etwas wie
MoyaProvider<Service>.request(.sendForgotPassword(email: "[email protected]"))
tun würde, aber jetzt stellen Sie sich möchte zwischen Ihrer Produktion und dem Testserver unterscheiden. Wenn Sie einen Server als ein anderes Tupelelement jeweils hinzufügen:
case forgotPassword(sessionToken: String, serverBaseURLString: String)
dies wird sein, eine falsche Semantik, da man ursprünglich jedes Tupel beabsichtigen Anforderungsparameter zu speichern, aber jetzt speichert es eine Server-Basisadresse.
Um solche Dinge zu vermeiden, können wir unseren Typ folgendermaßen parametrisieren. Stattdessen Server von, wie definiert wird sagen:
enum Server: String {
case production = "https://service.info"
case test = "http://test.service.info"
}
wir es mit bestimmten Typ für jeden Fall wie definieren:
public struct ProductionServer: ServerType {
public static var baseURLString: String { return "https://service.info" }
}
public struct TestServer: ServerType {
public static var baseURLString: String { return "http://test.service.info" }
}
public protocol ServerType {
static var baseURLString: String { get }
}
und schließlich unsere Servicetype parametrisieren als
public enum Service<T> where T: ServerType {
case registerNewUser(username: String, password: String, language: String)
case login(username: String, password: String, deviceTokenº: String?)
case logout(sessionToken: String)
case sendForgotPassword(email: String)
var serverURL: URL {
return T.baseURL
}
}
public typealias ProdutionService = Service<ProductionServer>
public typealias TestService = Service<TestServer>
Aber Aufzählungen hatte gespeicherte Eigenschaften zunächst - http: // stackoverflow.com/questions/24029581/why-no-stored-type-properties-for-classes-in-swift –
Nun enum ist struct standardmäßig so vielleicht du kannst es erweitern und machen eine funktion, die das tun kann, aber ich sehe nicht Ein Grund dafür ... sie werden für statische, bekannte, berechnete Strukturen verwendet und der beste Weg sie zu benutzen ist so ... –