2016-08-05 56 views
2

Ich versuche herauszufinden, ob es möglich ist, Enum-Typ auf die gleiche Weise zu übergeben, wie Sie Class Objekte in Swift übergeben können.Möglich, einen Enum-Typ-Namen als ein Argument in Swift übergeben?

Meine eigentliche Anwendungsfall ist ein wenig komplizierter als das, aber für die Diskussion, sagen wir, ich habe zwei Int Aufzählungen:

enum Foo: Int, CustomStringConvertible { 
    case firstFoo = 0 
    case anotherFoo = 1 
    var description: String { 
     switch self { 
     case .firstFoo: 
      return "Hello Foo" 
     case .anotherFoo: 
      return "Goodbye Foo" 
     } 
    } 
} 

enum Bar: Int, CustomStringConvertible { 
    case firstBar = 0 
    case anotherBar = 1 
    var description: String { 
     switch self { 
     case . firstBar: 
      return "Hello Bar" 
     case . anotherBar: 
      return "Goodbye Bar" 
     } 
    } 
} 

Ich mag würde in der Lage sein, eine Funktion wie folgt zu schreiben:

func justAnExample(whichEnum: enum) { 
    let val = whichEnum(rawValue: 0) 
    print("description: \(String(val))") 
} 

Und dann ist es wie folgt zu verwenden:

justAnExample(Foo) 
// prints: "description: Hello Foo" 
justAnExample(Bar) 
// prints: "description: Hello Bar" 

Ist das möglich? Wenn ja, wie lautet die Signatur von whichEnum in der Funktionsdeklaration?

Antwort

4

Sie können Generika verwenden, um dies zu tun, um die Funktion Argument definieren, die Metatyp eines gegebenen T (T.Type) zu sein, wo die TRawRepresentable, und seine RawValue ist Int. Dadurch können Sie die Metatypen von Foo und Bar übergeben.

func justAnExample<T : RawRepresentable>(_ whichEnum: T.Type) where T.RawValue == Int { 

    // Note that an explicit use of init is required 
    // when creating an instance from a metatype. 
    // We're also using a guard, as init?(rawValue:) is failable. 
    guard let val = whichEnum.init(rawValue: 0) else { return } 
    print("description: \(val)") 
} 

justAnExample(Foo.self) // prints: "description: Hello Foo" 

justAnExample(Bar.self) // prints: "description: Hello Bar" 

Beachten Sie, dass vor dem Swift 3, können Sie die .self weglassen könnte von den Argumenten (die die Metatyp bekommt), aber Swift 3 wird eine Warnung generiert, wenn Sie dies tun.

+0

Schöne Verknüpfung zu den SO Dokumente +1 –

-1

Eine Lösung wäre, Erweiterung für RawRepresentable, E.G.

extension RawRepresentable where RawValue == Int{ 

    static func testPrint() { 
     print(Self(rawValue: 0)) 
    } 
} 
enum Thing: Int { 
    case Test = 0 
} 
// prints "Optional(Thing.Test)" 
Thing.testPrint() 

Dann müssen Sie sich nicht darum kümmern, etwas zu übergeben. Und natürlich wird es für mehr als nur Enums funktionieren

+0

Dies hilft nicht, weil ich 'Thing' nicht habe. Ich versuche, 'ThingA' oder' ThingB' als Argument zu übergeben, – Kevin

+0

Wenn es ThingA: Int und ThingB: Int ist, sollte es in Ordnung sein. Sie könnten auch eine Erweiterung für einen anderen RawValue-Typ schreiben – PeejWeej

+0

Dies löst das Problem jedoch nicht. Ich möchte 'someOtherMethod (Thing)', nicht 'Thing.testPrint()' nennen – Kevin