2015-12-01 5 views
7

Desidero creare un che imponga un determinato caso su tutto enums conforme a questo .Aggiunta di un caso a un enum esistente con un protocollo

Per esempio, se ho un enum come questo:

enum Foo{ 
    case bar(baz: String) 
    case baz(bar: String) 
} 

voglio estenderlo con un che aggiunge un altro caso:

case Fuzz(Int) 

è possibile?

risposta

21

design

Il lavoro attorno è quello di utilizzare un struct con static variabili.

Nota: Questo è ciò che viene fatto in Swift 3 per Notification.Name

seguito è un'implementazione su Swift 3

Struct:

struct Car : RawRepresentable, Equatable, Hashable, Comparable { 

    typealias RawValue = String 

    var rawValue: String 

    static let Red = Car(rawValue: "Red") 
    static let Blue = Car(rawValue: "Blue") 

    //MARK: Hashable 

    var hashValue: Int { 
     return rawValue.hashValue 
    } 

    //MARK: Comparable 

    public static func <(lhs: Car, rhs: Car) -> Bool { 

     return lhs.rawValue < rhs.rawValue 
    } 

} 

protocollo

protocol CoolCar { 

} 

extension CoolCar { 

    static var Yellow : Car { 

     return Car(rawValue: "Yellow") 
    } 
} 

extension Car : CoolCar { 

} 

Invocare

let c1 = Car.Red 


switch c1 { 
case Car.Red: 
    print("Car is red") 
case Car.Blue: 
    print("Car is blue") 
case Car.Yellow: 
    print("Car is yellow") 
default: 
    print("Car is some other color") 
} 

if c1 == Car.Red { 
    print("Equal") 
} 

if Car.Red > Car.Blue { 
    print("Red is greater than Blue") 
} 
5

no, dal momento che non è possibile dichiarare un case al di fuori di un enum.

4

Un extension può aggiungere una nidificato enum, in questo modo:

enum Plants { 
    enum Fruit { 
    case banana 
    } 
} 


extension Plants { 
    enum Vegetables { 
    case potato 
    } 
} 
0

Qui ci sono un paio aggiuntivo richiede che possono aiutare qualcuno là fuori:

Usando il tuo esempio:

enum Foo { 
    case bar(baz: String) 
    case baz(bar: String) 
} 

È possibile considerare r per "nido" in un case della propria enum:

enum FooExtended { 
    case foo(Foo) // <-- Here will live your instances of `Foo` 
    case fuzz(Int) 
} 

Con questa soluzione, diventa più laboriosa per accedere alla casi "nascosti" tipo associato. Ma questa semplificazione potrebbe effettivamente essere utile in alcune applicazioni.

Altri passaggi alternativi per appena ricreare ed estenderlo pur avendo un modo per convertire Foo nella esteso enumFooExtended (ad esempio con un costume init.):

enum FooExtended { 
    case bar(baz: String) 
    case baz(bar: String) 
    case fuzz(Int) 

    init(withFoo foo: Foo) { 
     switch foo { 
     case .bar(let baz): 
      self = .bar(baz: baz) 
     case .baz(let bar): 
      self = .baz(bar: bar) 
     } 
    } 
} 

Ci possono essere molti posti in cui uno, il altro, o entrambe queste soluzioni non hanno assolutamente senso, ma sono abbastanza sicuro che possano essere utili a qualcuno là fuori (anche se solo come esercizio).

Problemi correlati