Comment trouvez-vous le type d’un object (dans Swift)?

Lorsque vous essayez de comprendre un programme ou dans certains cas, il est utile de savoir quel type est quelque chose. Je sais que le débogueur peut vous montrer des informations de type, et vous pouvez généralement compter sur l’inférence de type pour ne pas spécifier le type dans ces situations, mais j’aimerais quand même avoir quelque chose comme le type() de Python type()

dynamicType (voir cette question )

Mise à jour: cela a été changé dans une version récente de Swift, obj.dynamicType vous donne maintenant une référence au type et non à l’instance du type dynamic.

Celui-ci semble le plus prometteur, mais jusqu’à présent, je n’ai pas pu trouver le type réel

 class MyClass { var count = 0 } let mc = MyClass() # update: this now evaluates as true mc.dynamicType === MyClass.self 

J’ai aussi essayé d’utiliser une référence de classe pour instancier un nouvel object, ce qui fonctionne, mais bizarrement, j’ai eu une erreur en disant que je devais append un initialiseur required :

travaux:

 class MyClass { var count = 0 required init() { } } let myClass2 = MyClass.self let mc2 = MyClass2() 

Encore un petit pas vers la découverte du type d’object donné

edit : J’ai supprimé un nombre important de détails non pertinents – regardez l’historique des modifications si cela vous intéresse 🙂

Version Swift 3:

 type(of: yourObject) 

Dans Swift 2.0, la méthode appropriée pour effectuer ce type d’introspection serait avec la structure Mirror ,

  let ssortingngObject:Ssortingng = "testing" let ssortingngArrayObject:[Ssortingng] = ["one", "two"] let viewObject = UIView() let anyObject:Any = "testing" let ssortingngMirror = Mirror(reflecting: ssortingngObject) let ssortingngArrayMirror = Mirror(reflecting: ssortingngArrayObject) let viewMirror = Mirror(reflecting: viewObject) let anyMirror = Mirror(reflecting: anyObject) 

Ensuite, pour accéder au type lui-même depuis la structure Mirror vous utiliseriez la propriété subjectType comme ceci:

  // Prints "Ssortingng" print(ssortingngMirror.subjectType) // Prints "Array" print(ssortingngArrayMirror.subjectType) // Prints "UIView" print(viewMirror.subjectType) // Prints "Ssortingng" print(anyMirror.subjectType) 

Vous pouvez alors utiliser quelque chose comme ceci:

  if anyMirror.subjectType == Ssortingng.self { print("anyObject is a ssortingng!") } else { print("anyObject is not a ssortingng!") } 

Le code “dynamicType.printClassName” provient d’un exemple du livre Swift. Je ne sais pas comment saisir directement un nom de classe personnalisé, mais vous pouvez vérifier un type d’instance en utilisant le mot-clé “is”, comme indiqué ci-dessous. Cet exemple montre également comment implémenter une fonction className personnalisée, si vous voulez vraiment le nom de la classe en tant que chaîne.

 class Shape { class func className() -> Ssortingng { return "Shape" } } class Square: Shape { override class func className() -> Ssortingng { return "Square" } } class Circle: Shape { override class func className() -> Ssortingng { return "Circle" } } func getShape() -> Shape { return Square() // hardcoded for example } let newShape: Shape = getShape() newShape is Square // true newShape is Circle // false newShape.dynamicType.className() // "Square" newShape.dynamicType.className() == Square.className() // true 

Notez que les sous-classes de NSObject implémentent déjà leur propre fonction className. Si vous travaillez avec Cocoa, vous pouvez simplement utiliser cette propriété.

 class MyObj: NSObject { init() { super.init() println("My class is \(self.className)") } } MyObj() 

A partir de Xcode 6.0.1 (du moins, pas sûr quand ils l’ont ajouté), votre exemple original fonctionne maintenant:

 class MyClass { var count = 0 } let mc = MyClass() mc.dynamicType === MyClass.self // returns `true` 

Mettre à jour:

Pour répondre à la question initiale, vous pouvez utiliser le runtime Obj-C avec des objects Swift simples avec succès.

Essayez ce qui suit:

 import Foundation class MyClass { } class SubClass: MyClass { } let mc = MyClass() let m2 = SubClass() // Both of these return .Some("__lldb_expr_35.SubClass"), which is the fully mangled class name from the playground Ssortingng.fromCSsortingng(class_getName(m2.dynamicType)) Ssortingng.fromCSsortingng(object_getClassName(m2)) // Returns .Some("__lldb_expr_42.MyClass") Ssortingng.fromCSsortingng(object_getClassName(mc)) 

Si vous avez simplement besoin de vérifier si la variable est de type X, ou si elle est conforme à un protocole, alors vous pouvez utiliser is , ou as? comme dans la suite:

 var unknownTypeVariable = … if unknownTypeVariable is  { //the variable is of type  } else { //variable is not of type  } 

Ceci est équivalent à isKindOfClass dans Obj-C.

Et ceci est équivalent à isMemberOfClass , ou isMemberOfClass

 var unknownTypeVariable = … if let myClass = unknownTypeVariable as?  { //unknownTypeVarible is of type  } else { //unknownTypeVariable is not of type  } 

Cela fonctionne dans swift 3

 if unknownType is MyClass { //unknownType is of class type MyClass } 

Voici deux façons de le faire:

 if let thisShape = aShape as? Square 

Ou:

 aShape.isKindOfClass(Square) 

Voici un exemple détaillé:

 class Shape { } class Square: Shape { } class Circle: Shape { } var aShape = Shape() aShape = Square() if let thisShape = aShape as? Square { println("Its a square") } else { println("Its not a square") } if aShape.isKindOfClass(Square) { println("Its a square") } else { println("Its not a square") } 

Pour Swift 3.0

 Ssortingng(describing: .self) 

Pour Swift 2.0 – 2.3

 Ssortingng() 

Dépend du cas d’utilisation. Mais supposons que vous vouliez faire quelque chose d’utile avec vos types “variables”. L’instruction Swift switch est très puissante et peut vous aider à obtenir les résultats que vous recherchez …

  let dd2 = ["x" : 9, "y" : "home9"] let dds = dd2.filter { let eIndex = "x" let eValue:Any = 9 var r = false switch eValue { case let testSsortingng as Ssortingng: r = $1 == testSsortingng case let testUInt as UInt: r = $1 == testUInt case let testInt as Int: r = $1 == testInt default: r = false } return r && $0 == eIndex } 

Dans ce cas, ayez un dictionnaire simple qui contient des paires clé / valeur qui peuvent être UInt, Int ou Ssortingng. Dans la méthode .filter() du dictionnaire, je dois vérifier que je .filter() les valeurs correctement et que je teste uniquement une chaîne lorsque c’est une chaîne, etc. L’instruction switch rend cela simple et sûr! En affectant 9 à la variable de type Any, le commutateur pour Int est exécuté. Essayez de le changer pour:

  let eValue:Any = "home9" 

..et réessayez. Cette fois, il exécute le cas as Ssortingng .

Si vous obtenez un avertissement “toujours vrai / échoue”, vous devrez peut-être lancer un avertissement sur Any avant d’utiliser

 (foo as Any) is SomeClass 
 //: Playground - noun: a place where people can play import UIKit class A { class func a() { print("yeah") } func getInnerValue() { self.dynamicType.a() } } class B: A { override class func a() { print("yeah yeah") } } Ba() // yeah yeah Aa() // yeah B().getInnerValue() // yeah yeah A().getInnerValue() // yeah