Comment imprimer le type ou la classe d'une variable dans Swift?

335

Existe-t-il un moyen d'imprimer le type d'exécution d'une variable dans Swift? Par exemple:

var now = NSDate()
var soon = now.dateByAddingTimeInterval(5.0)

println("\(now.dynamicType)") 
// Prints "(Metatype)"

println("\(now.dynamicType.description()")
// Prints "__NSDate" since objective-c Class objects have a "description" selector

println("\(soon.dynamicType.description()")
// Compile-time error since ImplicitlyUnwrappedOptional<NSDate> has no "description" method

Dans l'exemple ci-dessus, je cherche un moyen de montrer que la variable "bientôt" est de type ImplicitlyUnwrappedOptional<NSDate>, ou du moins NSDate!.

Matt Bridges
la source
43
@JasonMArcher Dites-moi en quoi est-ce un doublon si la question que vous avez liée a été posée 4 jours après celle-ci?
akashivskyy
Il existe un certain nombre de questions sur le test du type d'un objet Swift ou la lecture du type d'un objet Swift. Nous ne faisons que trouver les meilleures questions à utiliser comme questions «principales» pour ce sujet. Le doublon suggéré a une réponse beaucoup plus approfondie. Cela ne veut pas dire que vous avez fait quelque chose de mal, juste que nous essayons de réduire l'encombrement.
JasonMArcher
4
Le doublon suggéré ne répond pas à la même question; Type.self ne peut pas être imprimé sur la console à des fins de débogage, il est destiné à être utilisé pour passer à d'autres fonctions qui prennent Types comme objets.
Matt Bridges
2
OT: Très étrange que Swift ne propose pas cela hors de la boîte et il faut jouer avec ces bibliothèques C de bas niveau. Vaut un rapport de bug?
qwerty_so
Les gars, j'ai fourni ma réponse ci-dessous. Veuillez jeter un œil et faites-moi savoir si c'est ce à quoi vous vous attendez.
DILIP KOSURI

Réponses:

377

Mise à jour de septembre 2016

Swift 3.0: Utiliser type(of:), par exemple type(of: someThing)(puisque le dynamicTypemot - clé a été supprimé)

Mise à jour d'octobre 2015 :

J'ai mis à jour les exemples ci-dessous pour la nouvelle syntaxe Swift 2.0 (par exemple, a printlnété remplacé par print, toString()est maintenant String()).

À partir des notes de publication de Xcode 6.3 :

@nschum souligne dans les commentaires que les notes de publication de Xcode 6.3 montrent une autre manière:

Les valeurs de type s'impriment désormais en tant que nom de type démangé complet lorsqu'elles sont utilisées avec println ou une interpolation de chaîne.

import Foundation

class PureSwiftClass { }

var myvar0 = NSString() // Objective-C class
var myvar1 = PureSwiftClass()
var myvar2 = 42
var myvar3 = "Hans"

print( "String(myvar0.dynamicType) -> \(myvar0.dynamicType)")
print( "String(myvar1.dynamicType) -> \(myvar1.dynamicType)")
print( "String(myvar2.dynamicType) -> \(myvar2.dynamicType)")
print( "String(myvar3.dynamicType) -> \(myvar3.dynamicType)")

print( "String(Int.self)           -> \(Int.self)")
print( "String((Int?).self         -> \((Int?).self)")
print( "String(NSString.self)      -> \(NSString.self)")
print( "String(Array<String>.self) -> \(Array<String>.self)")

Quelles sorties:

String(myvar0.dynamicType) -> __NSCFConstantString
String(myvar1.dynamicType) -> PureSwiftClass
String(myvar2.dynamicType) -> Int
String(myvar3.dynamicType) -> String
String(Int.self)           -> Int
String((Int?).self         -> Optional<Int>
String(NSString.self)      -> NSString
String(Array<String>.self) -> Array<String>

Mise à jour pour Xcode 6.3:

Vous pouvez utiliser _stdlib_getDemangledTypeName():

print( "TypeName0 = \(_stdlib_getDemangledTypeName(myvar0))")
print( "TypeName1 = \(_stdlib_getDemangledTypeName(myvar1))")
print( "TypeName2 = \(_stdlib_getDemangledTypeName(myvar2))")
print( "TypeName3 = \(_stdlib_getDemangledTypeName(myvar3))")

et obtenez ceci en sortie:

TypeName0 = NSString
TypeName1 = __lldb_expr_26.PureSwiftClass
TypeName2 = Swift.Int
TypeName3 = Swift.String

Réponse originale:

Avant Xcode 6.3 _stdlib_getTypeName, le nom de type modifié d'une variable était obtenu. L'entrée de blog d'Ewan Swick permet de déchiffrer ces chaînes:

par exemple, _TtSireprésente le Inttype interne de Swift .

Mike Ash a une excellente entrée de blog couvrant le même sujet .

Klaas
la source
2
Comment avez-vous trouvé _stdlib_getTypeName()? Le REPL intégré n'existe plus, swift-ide-testn'existe pas non plus, et l'impression par Xcode du module Swift _élude les valeurs préfixées.
Lily Ballard
10
On dirait que je peux rechercher des symboles avec lldbassez facilement dans la réplique. Il y a aussi _stdlib_getDemangledTypeName(), et _stdlib_demangleName().
Lily Ballard
1
Oh bien, je ne savais pas que imagec'était un raccourci target modules. J'ai fini par utiliser target modules lookup -r -n _stdlib_, ce qui bien sûr est mieux exprimé commeimage lookup -r -n _stdlib_ libswiftCore.dylib
Lily Ballard
1
FYI - On dirait que toString (...) a été remplacé par String (...).
Nick
6
Swift 3.0: le dynamicTypemot clé a été supprimé de Swift. A sa place, une nouvelle fonction primitive type(of:)a été ajoutée au langage: github.com/apple/swift/blob/master/CHANGELOG.md
Szu
46

Edit: Une nouvelle toStringfonction a été introduite dans Swift 1.2 (Xcode 6.3) .

Vous pouvez maintenant imprimer le type démangé de n'importe quel type à l'aide de .selfet n'importe quelle instance à l'aide de .dynamicType:

struct Box<T> {}

toString("foo".dynamicType)            // Swift.String
toString([1, 23, 456].dynamicType)     // Swift.Array<Swift.Int>
toString((7 as NSNumber).dynamicType)  // __NSCFNumber

toString((Bool?).self)                 // Swift.Optional<Swift.Bool>
toString(Box<SinkOf<Character>>.self)  // __lldb_expr_1.Box<Swift.SinkOf<Swift.Character>>
toString(NSStream.self)                // NSStream

Essayez d'appeler YourClass.selfet yourObject.dynamicType.

Référence: https://devforums.apple.com/thread/227425 .

akashivskyy
la source
2
J'ai répondu à ce fil, mais je vais ajouter mon commentaire ici. Ces valeurs sont de type "Metatype", mais il ne semble pas y avoir de moyen facile de comprendre quel type représente un objet Metatype, ce que je recherche.
Matt Bridges
Ils sont de type Metatype et ce sont des classes. Ils représentent une classe. Je ne sais pas exactement quel est votre problème avec ça. someInstance.dynamicType.printClassName()affichera le nom de la classe.
Fichier analogique
18
la méthode printClassName () n'est qu'un exemple de méthode qu'ils ont créée dans l'un des exemples des documents, ce n'est pas un appel d'API auquel vous pouvez accéder.
Dave Wood
4
FYI - On dirait que toString (...) a été remplacé par String (...)
Nick
33

Swift 3.0

let string = "Hello"
let stringArray = ["one", "two"]
let dictionary = ["key": 2]

print(type(of: string)) // "String"

// Get type name as a string
String(describing: type(of: string)) // "String"
String(describing: type(of: stringArray)) // "Array<String>"
String(describing: type(of: dictionary)) // "Dictionary<String, Int>"

// Get full type as a string
String(reflecting: type(of: string)) // "Swift.String"
String(reflecting: type(of: stringArray)) // "Swift.Array<Swift.String>"
String(reflecting: type(of: dictionary)) // "Swift.Dictionary<Swift.String, Swift.Int>"
Evgenii
la source
1
L'implémentation de Swift 2 est particulièrement agréable avec les cas d'énumération. Quelqu'un sait-il si ce comportement est documenté / garanti par Apple? La bibliothèque standard inclut simplement un commentaire indiquant que cela convient au débogage ...
milos
30

C'est ce que vous cherchez?

println("\(object_getClassName(now))");

Il imprime "__NSDate"

MISE À JOUR : Veuillez noter que cela ne semble plus fonctionner à partir de Beta05

Haiku Oezu
la source
2
Ne fonctionne pas pour les cours rapides. Renvoie "UnsafePointer (0x7FBB18D06DE0)"
aryaxt
4
Ne fonctionne pas non plus pour les classes ObjC (au moins en Beta5), pour un NSManagedObject, je reçois juste "Builtin.RawPointer = address"
Kendall Helmstetter Gelner
23

Mon Xcode actuel est la version 6.0 (6A280e).

import Foundation

class Person { var name: String; init(name: String) { self.name = name }}
class Patient: Person {}
class Doctor: Person {}

var variables:[Any] = [
    5,
    7.5,
    true,
    "maple",
    Person(name:"Sarah"),
    Patient(name:"Pat"),
    Doctor(name:"Sandy")
]

for variable in variables {
    let typeLongName = _stdlib_getDemangledTypeName(variable)
    let tokens = split(typeLongName, { $0 == "." })
    if let typeName = tokens.last {
        println("Variable \(variable) is of Type \(typeName).")
    }
}

Production:

Variable 5 is of Type Int.
Variable 7.5 is of Type Double.
Variable true is of Type Bool.
Variable maple is of Type String.
Variable Swift001.Person is of Type Person.
Variable Swift001.Patient is of Type Patient.
Variable Swift001.Doctor is of Type Doctor.
Matt Hagen
la source
1
Bien, mais la question incluait également les options, la sortie des options est définie Optional(...), donc votre code ne retournerait Optionalque comme type. Il doit également s'afficher var optionalTestVar: Person? = Person(name:"Sarah")comme facultatif (personne) et var avec personne! as ImplicitlyUnwrappedOptional (Person)
Binarian
18

À partir de Xcode 6.3 avec Swift 1.2, vous pouvez simplement convertir les valeurs de type en démanglé complet String.

toString(Int)                   // "Swift.Int"
toString(Int.Type)              // "Swift.Int.Type"
toString((10).dynamicType)      // "Swift.Int"
println(Bool.self)              // "Swift.Bool"
println([UTF8].self)            // "Swift.Array<Swift.UTF8>"
println((Int, String).self)     // "(Swift.Int, Swift.String)"
println((String?()).dynamicType)// "Swift.Optional<Swift.String>"
println(NSDate)                 // "NSDate"
println(NSDate.Type)            // "NSDate.Type"
println(WKWebView)              // "WKWebView"
toString(MyClass)               // "[Module Name].MyClass"
toString(MyClass().dynamicType) // "[Module Name].MyClass"
kiding
la source
L'autre sens est-il possible en 1.2? Pour initialiser une instance basée sur le nom de classe?
user965972
@ user965972 Pour autant que je sache, je ne pense pas qu'il y en ait.
kiding
17

Vous pouvez toujours accéder à la classe via className(qui renvoie a String).

Il y a en fait plusieurs façons d'obtenir la classe, par exemple classForArchiver , classForCoder, classForKeyedArchiver(tout retour AnyClass!).

Vous ne pouvez pas obtenir le type d'une primitive (une primitive n'est pas une classe).

Exemple:

var ivar = [:]
ivar.className // __NSDictionaryI

var i = 1
i.className // error: 'Int' does not have a member named 'className'

Si vous voulez obtenir le type d'une primitive, vous devez utiliser bridgeToObjectiveC(). Exemple:

var i = 1
i.bridgeToObjectiveC().className // __NSCFNumber
Leandros
la source
Je parie que c'est une primitive. Malheureusement, vous ne pouvez pas obtenir le type d'une primitive.
Leandros
Ces exemples ne semblent pas fonctionner dans la cour de récréation. J'obtiens l'erreur pour les primitives et les non-primitives.
Matt Bridges
essayez de import Cocoa.
Leandros
9
className semble être uniquement disponible pour NSObjects lors du développement pour OSX; il n'est pas disponible dans le SDK iOS pour NSObjects ou des objets "normaux"
Matt Bridges
3
classNamefait partie du support AppleScript de Cocoa et ne doit certainement pas être utilisé pour une introspection générique. Évidemment, il n'est pas disponible sur iOS.
Nikolai Ruhe
16

Vous pouvez utiliser la réflexion pour obtenir des informations sur l'objet.
Par exemple, le nom de la classe d'objets:

var nom_classe = refléter (maintenant) .summary
Stan
la source
Dans la version bêta 6, cela m'a donné le nom de l'application + le nom de la classe sous une forme légèrement modifiée, mais c'est un début. +1 pour reflect(x).summary- merci!
Olie
n'a pas fonctionné, imprime une ligne vierge dans Swift 1.2 Xcode 6.4 et iOs 8.4
Juan Boero
13

J'ai eu de la chance avec:

let className = NSStringFromClass(obj.dynamicType)
mxcl
la source
@hdost mec rien n'a fonctionné mais classForCoder a fonctionné.
Satheeshwaran
12

Type d'utilisation de Xcode 8 Swift 3.0 (of :)

let className = "\(type(of: instance))"
Hari Kunwar
la source
10

Dans Xcode 8, Swift 3.0

Pas:

1. Obtenez le type:

Option 1:

let type : Type = MyClass.self  //Determines Type from Class

Option 2:

let type : Type = type(of:self) //Determines Type from self

2. Convertissez le type en chaîne:

let string : String = "\(type)" //String
user1046037
la source
8

Dans Swift 3.0, vous pouvez utiliser type(of:), car le dynamicTypemot-clé a été supprimé.

Bruno Serrano
la source
7

SWIFT 5

Avec la dernière version de Swift 3, nous pouvons obtenir de jolies descriptions des noms de type via l' Stringinitialiseur. Comme, par exemple print(String(describing: type(of: object))). Où object peut être une variable d'instance comme un tableau, un dictionnaire, un Int, un NSDate, une instance d'une classe personnalisée, etc.

Voici ma réponse complète: obtenir le nom de classe de l'objet sous forme de chaîne dans Swift

Cette question cherche un moyen d'obtenir le nom de classe d'un objet sous forme de chaîne, mais j'ai également proposé un autre moyen d'obtenir le nom de classe d'une variable qui n'est pas une sous-classe de NSObject. C'est ici:

class Utility{
    class func classNameAsString(obj: Any) -> String {
        //prints more readable results for dictionaries, arrays, Int, etc
        return String(describing: type(of: obj))
    }
}

J'ai fait une fonction statique qui prend en paramètre un objet de type Anyet retourne son nom de classe comme String:).

J'ai testé cette fonction avec quelques variables comme:

    let diccionary: [String: CGFloat] = [:]
    let array: [Int] = []
    let numInt = 9
    let numFloat: CGFloat = 3.0
    let numDouble: Double = 1.0
    let classOne = ClassOne()
    let classTwo: ClassTwo? = ClassTwo()
    let now = NSDate()
    let lbl = UILabel()

et la sortie était:

  • diccionary est de type Dictionary
  • tableau est de type Array
  • numInt est de type Int
  • numFloat est de type CGFloat
  • numDouble est de type Double
  • classOne est de type: ClassOne
  • classTwo est de type: ClassTwo
  • est maintenant de type: Date
  • lbl est de type: UILabel
mauricioconde
la source
5

Lorsque vous utilisez Cocoa (et non CocoaTouch), vous pouvez utiliser la classNamepropriété pour les objets qui sont des sous-classes de NSObject.

println(now.className)

Cette propriété n'est pas disponible pour les objets Swift normaux, qui ne sont pas des sous-classes de NSObject (et en fait, il n'y a pas d'ID racine ou de type d'objet dans Swift).

class Person {
    var name: String?
}

var p = Person()
println(person.className) // <- Compiler error

Dans CocoaTouch, pour le moment, il n'existe aucun moyen d'obtenir une description de chaîne du type d'une variable donnée. Des fonctionnalités similaires n'existent pas non plus pour les types primitifs dans Cocoa ou CocoaTouch.

Le Swift REPL est capable d'imprimer un résumé des valeurs, y compris son type, il est donc possible que cette manière d'introspection soit possible via une API à l'avenir.

EDIT : dump(object)semble faire l'affaire.

Matt Bridges
la source
Même à partir de Xcode 10 et Swift 4.2, il dump(object)est vraiment puissant. Je vous remercie.
Alex Zavatone
5

La première réponse n'a pas d'exemple de travail de la nouvelle façon de procéder en utilisant type(of:. Donc, pour aider les débutants comme moi, voici un exemple de travail, tiré principalement des documents d'Apple ici - https://developer.apple.com/documentation/swift/2885064-type

doubleNum = 30.1

func printInfo(_ value: Any) {
    let varType = type(of: value)
    print("'\(value)' of type '\(varType)'")
}

printInfo(doubleNum)
//'30.1' of type 'Double'
Joshua Dance
la source
4

J'ai essayé certaines des autres réponses ici, mais le kilométrage semble très bien sur ce qu'est l'objet sous-jacent.

Cependant, j'ai trouvé un moyen d'obtenir le nom de classe Object-C d'un objet en procédant comme suit:

now?.superclass as AnyObject! //replace now with the object you are trying to get the class name for

Voici un exemple d'utilisation que vous en feriez:

let now = NSDate()
println("what is this = \(now?.superclass as AnyObject!)")

Dans ce cas, il imprimera NSDate dans la console.

James Jones
la source
4

J'ai trouvé cette solution qui, je l'espère, pourrait fonctionner pour quelqu'un d'autre. J'ai créé une méthode de classe pour accéder à la valeur. Veuillez garder à l'esprit que cela ne fonctionnera que pour la sous-classe NSObject. Mais au moins, c'est une solution propre et bien rangée.

class var className: String!{
    let classString : String = NSStringFromClass(self.classForCoder())
    return classString.componentsSeparatedByString(".").last;
}
DennyLou
la source
4

Dans le dernier XCode 6.3 avec Swift 1.2, c'est le seul moyen que j'ai trouvé:

if view.classForCoder.description() == "UISegment" {
    ...
}
Joel Kopelioff
la source
REMARQUE: description () renvoie le nom de la classe au format <swift module name>.<actual class name>, vous voulez donc diviser la chaîne avec a .et obtenir le dernier jeton.
Matthew Quiros
4

Beaucoup de réponses ici ne fonctionnent pas avec la dernière Swift (Xcode 7.1.1 au moment de la rédaction).

La manière actuelle d'obtenir les informations est de créer Mirroret d'interroger cela. Pour le nom de classe, c'est aussi simple que:

let mirror = Mirror(reflecting: instanceToInspect)
let classname:String = mirror.description

Des informations supplémentaires sur l'objet peuvent également être récupérées à partir du Mirror. Voir http://swiftdoc.org/v2.1/type/Mirror/ pour plus de détails.

Joseph Lord
la source
Quel est le problème avec les réponses stackoverflow.com/a/25345480/1187415 et stackoverflow.com/a/32087449/1187415 ? Les deux semblent fonctionner assez bien avec Swift 2. (Je n'ai pas vérifié les autres.)
Martin R
J'aime cela comme solution générale, mais obtenir "Mirror for ViewController" ("Mirror for" superflu) - attendez, il semble que l'utilisation de ".subjectType" fasse l'affaire!
David H
3

Dans lldb à partir de la bêta 5, vous pouvez voir la classe d'un objet avec la commande:

fr v -d r shipDate

qui génère quelque chose comme:

(DBSalesOrderShipDate_DBSalesOrderShipDate_ *) shipDate = 0x7f859940

La commande développée signifie quelque chose comme:

Frame Variable (imprimer une variable de cadre) -d run_target (développer les types dynamiques)

Il est utile de savoir que l'utilisation de "Frame Variable" pour générer des valeurs de variable garantit qu'aucun code n'est exécuté.

Kendall Helmstetter Gelner
la source
3

J'ai trouvé une solution pour les classes auto-développées (ou celles auxquelles vous avez accès).

Placez la propriété calculée suivante dans votre définition de classe d'objets:

var className: String? {
    return __FILE__.lastPathComponent.stringByDeletingPathExtension
}

Maintenant, vous pouvez simplement appeler le nom de la classe sur votre objet comme ceci:

myObject.className

Veuillez noter que cela ne fonctionnera que si votre définition de classe est faite dans un fichier qui est nommé exactement comme la classe dont vous voulez le nom.

Comme c'est généralement le cas, la réponse ci-dessus devrait le faire pour la plupart des cas . Mais dans certains cas particuliers, vous devrez peut-être trouver une solution différente.


Si vous avez besoin du nom de classe dans la classe (fichier) elle-même, vous pouvez simplement utiliser cette ligne:

let className = __FILE__.lastPathComponent.stringByDeletingPathExtension

Peut-être que cette méthode aide certaines personnes.

Jeehut
la source
3

Sur la base des réponses et des commentaires donnés par Klass et Kevin Ballard ci-dessus, j'irais avec:

println(_stdlib_getDemangledTypeName(now).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(soon).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(soon?).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(soon!).componentsSeparatedByString(".").last!)

println(_stdlib_getDemangledTypeName(myvar0).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(myvar1).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(myvar2).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(myvar3).componentsSeparatedByString(".").last!)

qui imprimera:

"NSDate"
"ImplicitlyUnwrappedOptional"
"Optional"
"NSDate"

"NSString"
"PureSwiftClass"
"Int"
"Double"
Vince O'Sullivan
la source
Je pense que c'est la meilleure réponse.
maschall
J'ai fini par utiliser dans Swift 1.2 ce qui suit toString(self.dynamicType).componentsSeparatedByString(".").last!:, évidemment, j'étais dans un contexte d'objet et capable de faire référence self.
Joe
3
let i: Int = 20


  func getTypeName(v: Any) -> String {
    let fullName = _stdlib_demangleName(_stdlib_getTypeName(i))
    if let range = fullName.rangeOfString(".") {
        return fullName.substringFromIndex(range.endIndex)
    }
    return fullName
}

println("Var type is \(getTypeName(i)) = \(i)")
Alex Burla
la source
3

Swift version 4:

print("\(type(of: self)) ,\(#function)")
// within a function of a class

Merci @Joshua Dance

dengApro
la source
3

Swift 4:

// "TypeName"
func stringType(of some: Any) -> String {
    let string = (some is Any.Type) ? String(describing: some) : String(describing: type(of: some))
    return string
}

// "ModuleName.TypeName"
func fullStringType(of some: Any) -> String {
    let string = (some is Any.Type) ? String(reflecting: some) : String(reflecting: type(of: some))
    return string
}

Usage:

print(stringType(of: SomeClass()))     // "SomeClass"
print(stringType(of: SomeClass.self))  // "SomeClass"
print(stringType(of: String()))        // "String"
print(fullStringType(of: String()))    // "Swift.String"
Desmond Hume
la source
2

Il ne semble pas y avoir de moyen générique pour imprimer le nom de type du type d'une valeur arbitraire. Comme d'autres l'ont noté, pour les instances de classe , vous pouvez imprimer value.classNamemais pour les valeurs primitives, il semble qu'au moment de l'exécution, les informations de type ont disparu.

Par exemple, il semble qu'il n'y ait aucun moyen de taper: 1.something()et de sortir Intpour n'importe quelle valeur de something. (Vous pouvez, comme une autre réponse l'a suggéré, utiliser i.bridgeToObjectiveC().classNamepour vous donner un indice, mais ce __NSCFNumbern'est pas vraiment le type de i- juste ce à quoi il sera converti lorsqu'il franchira la limite d'un appel de fonction Objective-C.)

Je serais heureux d'avoir tort, mais il semble que la vérification de type soit entièrement effectuée au moment de la compilation, et comme C ++ (avec RTTI désactivé), la plupart des informations de type ont disparu au moment de l'exécution.

ipmcc
la source
Pouvez-vous donner un exemple d'utilisation de className pour imprimer "NSDate" pour la variable "now" dans mon exemple qui fonctionne dans la cour de récréation de Xcode6? Pour autant que je sache, className n'est pas défini sur les objets Swift, même ceux qui sont des sous-classes de NSObject.
Matt Bridges du
Il semble que 'className' soit disponible pour les objets qui descendent de NSObject, mais uniquement lors du développement pour mac, pas pour iOS. Il ne semble pas y avoir de solution de contournement pour iOS.
Matt Bridges
1
Oui, le vrai point à retenir ici semble être que, dans le cas général, les informations de type ont disparu au moment de l'exécution dans swift.
ipmcc
Je suis curieux de savoir comment le REPL est capable d'imprimer les types de valeurs, cependant.
Matt Bridges
Le REPL est presque certainement interprété et non compilé, ce qui pourrait facilement l'expliquer
ipmcc
2

C'est ainsi que vous obtenez une chaîne de type de votre objet ou Type qui est cohérent et prend en compte à quel module la définition d'objet appartient ou est imbriquée. Fonctionne dans Swift 4.x.

@inline(__always) func typeString(for _type: Any.Type) -> String {
    return String(reflecting: type(of: _type))
}

@inline(__always) func typeString(for object: Any) -> String {
    return String(reflecting: type(of: type(of: object)))
}

struct Lol {
    struct Kek {}
}

// if you run this in playground the results will be something like
typeString(for: Lol.self)    //    __lldb_expr_74.Lol.Type
typeString(for: Lol())       //    __lldb_expr_74.Lol.Type
typeString(for: Lol.Kek.self)//    __lldb_expr_74.Lol.Kek.Type
typeString(for: Lol.Kek())   //    __lldb_expr_74.Lol.Kek.Type
Igor Muzyka
la source
2

Pour obtenir un type d'objet ou une classe d'objet dans Swift , vous devez utiliser un type (de: yourObject)

type (de: votreObjet)

Rahul Panzade
la source
1

Pas exactement ce que vous recherchez, mais vous pouvez également vérifier le type de la variable par rapport aux types Swift comme ceci:

let object: AnyObject = 1

if object is Int {
}
else if object is String {
}

Par exemple.

PersuitOfPerfection
la source
1

Xcode 7.3.1, Swift 2.2:

String(instanceToPrint.self).componentsSeparatedByString(".").last

leanne
la source