2015-05-05 9 views
10

Ich versuche, einen Typ in einer Variablen zu speichern, so dass ich es später wie ein 1. Klasse-Typ verwenden kann.Speichern Typ in Variable, um wie ein Typ später zu verwenden

class SomeModel {} 

let someType = SomeModel.self 
let array = Array<someType>() 

In diesem Fall sicher, dass ich Array<SomeModel>() stattdessen getan haben könnte, aber ich will es verallgemeinern und lassen Subklassen den Wert von someType liefern.

Allerdings bekomme ich Fehler wie someType isn't a type oder use of undeclared type 'someType' auf der letzten Zeile.

Antwort

10
func someFunc<T>(model: T) -> Array<T> { 
    let array = Array<T>() 
    return array 
} 

let someType = SomeModel.self 
let array = someFunc(someType()) 

Sieht aus wie das, was ich will. Der einzige Nachteil ist, dass ich eine Instanz des gewünschten Typs erstellen muss. In diesem Fall ist sein minimaler Aufwand, aber es scheint nur eine Verschwendung.

Eine andere Sache mit der Verwendung von Generika wie dieser scheint es, dass die generischen möglichen Typen zur Kompilierzeit berechnet werden, so dass zur Laufzeit model.dynamicType nicht unbedingt T entspricht. In den meisten Fällen wird es das tun, aber wenn Sie reflexionsgetriebene Dinge tun, stellen Sie sicher, dass Sie Ihren Anwendungsfall gut überprüfen.

+12

Sie müssen keine Instanz erstellen, Sie können einfach 'func someFunc (Modell: T.Type) -> Array {...' – thesummersign

0

Heutzutage kann dies einfacher und besser erreicht werden, indem .Type für eine Klasse oder ein Protokoll verwendet wird. Beachten Sie, dass nur auf Funktionen zugegriffen werden kann, die für diese Stammklasse oder dieses Protokoll verfügbar sind. Daher sollten Sie sicherstellen, dass ein erforderlicher Initialisierer definiert ist. Zum Beispiel:

protocol MyClass { 
    init(someValue: Int) 
} 

class MyWrapper { 

    let myClassType: MyClass.Type 

    init(classType: MyClass.Type) { 
     self.myClassType = classType 
    } 

    func new(with value: Int) -> MyClassType { 
     return MyClassType.init(someValue: value) 
    } 

} 

Sie können nun diese eher albert Factory-Klasse mit einer bestimmten Klasse initialisieren das MyClass-Protokoll implementiert und wenn Sie die new() Funktion mit einem ganzzahligen Wert nennen es eine neue Instanz dieser Klasse erzeugen und zurückgeben .

Verwandte Themen