如何在Swift中打印变量的类型或类别?

如何在Swift中打印变量的类型或类别?,swift,types,Swift,Types,有没有办法在swift中打印变量的运行时类型?例如: 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

有没有办法在swift中打印变量的运行时类型?例如:

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
var now=NSDate()
var soon=now.dateByAddingTimeInterval(5.0)
println(“\(now.dynamicType)”)
//“打印”(元类型)
println(“\(now.dynamicType.description()”)
//打印“\uu NSDate”,因为objective-c类对象有一个“description”选择器
println(“\(soon.dynamicType.description()”)
//编译时错误,因为隐式WrappedOptional没有“description”方法

在上面的示例中,我正在寻找一种方法来显示变量“soon”的类型是
隐式的WrappedOptional
,或者至少是
NSDate!
您仍然可以通过
className
访问该类(它返回一个
字符串

实际上有几种方法可以获取类,例如
classForArchiver
classForCoder
classforkeydarchiver
(全部返回
AnyClass!

无法获取基元的类型(基元不是类)

例如:

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

var i = 1
i.className // error: 'Int' does not have a member named 'className'
如果要获取基元的类型,必须使用
bridgeToObjectiveC()
。示例:

var i = 1
i.bridgeToObjectiveC().className // __NSCFNumber

编辑:一个新的
toString
函数。

现在,您可以使用
.self
打印任何类型的demangled类型,也可以使用
.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
struct-Box{}
toString(“foo.dynamicType)//Swift.String
toString([1,23456].dynamicType)//Swift.Array
toString((7作为NSNumber.dynamicType)/\uU NSCFNumber
toString((Bool?.self)//Swift.Optional
toString(Box.self)/\ulldb\uexpr\u1.Box
toString(NSStream.self)//NSStream

尝试调用
YourClass.self
yourObject.dynamicType


参考:。

似乎没有通用的方法来打印任意值类型的类型名。正如其他人所指出的,对于类实例,可以打印
value.className
,但对于基本值,在运行时,类型信息似乎消失了

例如,似乎没有一种方法可以键入:
1.something()
并从
Int
中取出
something
的任何值(正如另一个答案所建议的,您可以使用
i.bridgeToObjectiveC().className
给您一个提示,但是
\uu NSCFNumber
实际上不是
i
的类型——只是当它跨越Objective-C函数调用的边界时将转换为的类型。)

我很高兴被证明是错误的,但是看起来类型检查都是在编译时完成的,像C++一样(RTTI禁用),很多类型信息在运行时都已经消失了。

< P>当使用COCOA(不COOTATUCH)时,可以使用NSObjult/Sp><
println(now.className)
此属性不适用于普通的Swift对象,它们不是NSObject的子类(事实上,Swift中没有根id或对象类型)

班级人员{
变量名称:字符串?
}
var p=个人()

println(person.className)//这就是您要找的吗

println("\(object_getClassName(now))");
它会打印“\uu NSDate”


更新:请注意,从Beta05开始,这似乎不再起作用。您可以使用“反射”获取有关对象的信息。
例如,对象类的名称:

var classname = reflect(now).summary var classname=reflect(now).summary
在从beta 5开始的lldb中,您可以通过以下命令查看对象的类:

fr v -d r shipDate
其输出类似于:

(DBSalesOrderShipDate_DBSalesOrderShipDate_ *) shipDate = 0x7f859940
“展开”命令的含义如下:

(DBSalesOrderShipDate_DBSalesOrderShipDate_ *) shipDate = 0x7f859940
帧变量
(打印帧变量)
-d运行\u目标
(展开动态类型)


需要知道的是,使用“帧变量”输出变量值可以保证不执行任何代码。

2016年9月更新

Swift 3.0:使用
类型(of:)
,例如
类型(of:someThing)
(因为
dynamicType
关键字已被删除)

2015年10月更新

我将下面的示例更新为新的Swift 2.0语法(例如,
println
替换为
print
toString()
现在是
String()

来自Xcode 6.3发行说明

@nschum在评论中指出,这表明了另一种方式:

当与一起使用时,类型值现在打印为完整的demangled类型名称 println或字符串插值

并将其作为输出:

TypeName0 = NSString
TypeName1 = __lldb_expr_26.PureSwiftClass
TypeName2 = Swift.Int
TypeName3 = Swift.String
原始答复:

Xcode 6.3之前的版本
\u stdlib\u getTypeName
获取了变量的损坏类型名称。有助于破译这些字符串:

e、 g.
\u TtSi
代表Swift的内部
Int
类型

.

我很幸运:

let className = NSStringFromClass(obj.dynamicType)

我当前的Xcode是6.0版(6A280e)

输出:

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.

我在这里尝试了一些其他的答案,但milage似乎非常关注下面的对象是什么

但是,我确实找到了一种方法,您可以通过执行以下操作获得对象的Object-C类名:

now?.superclass as AnyObject! //replace now with the object you are trying to get the class name for
下面是您将如何使用它的示例:

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

在这种情况下,它将在控制台中打印NSDate。

我发现了一个针对自主开发类的解决方案(或您可以访问的类)

将以下计算属性放置在对象类定义中:

var className: String? {
    return __FILE__.lastPathComponent.stringByDeletingPathExtension
}
现在,您可以简单地调用对象上的类名,如下所示:

myObject.className
请注意,只有在
您的类定义是在一个名为
的文件中创建的,并且该文件与您想要的类名完全相同的情况下,才有效

由于这是一种常见的情况上述答案应该适用于大多数情况。但在某些特殊情况下,您可能需要找出不同的解决方案

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

如果需要类(文件)本身中的类名只需使用以下行:

let className = __FILE__.lastPathComponent.stringByDeletingPathExtension

也许这个方法对一些人有帮助
var className: String? {
    return __FILE__.lastPathComponent.stringByDeletingPathExtension
}
myObject.className
let className = __FILE__.lastPathComponent.stringByDeletingPathExtension
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!)
"NSDate"
"ImplicitlyUnwrappedOptional"
"Optional"
"NSDate"

"NSString"
"PureSwiftClass"
"Int"
"Double"
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)")
class var className: String!{
    let classString : String = NSStringFromClass(self.classForCoder())
    return classString.componentsSeparatedByString(".").last;
}
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"
class Utility{
    class func classNameAsString(obj: Any) -> String {
        //prints more readable results for dictionaries, arrays, Int, etc
        return String(describing: type(of: obj))
    }
}
    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()
if view.classForCoder.description() == "UISegment" {
    ...
}
let object: AnyObject = 1

if object is Int {
}
else if object is String {
}
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>"
let mirror = Mirror(reflecting: instanceToInspect)
let classname:String = mirror.description
let className = "\(type(of: instance))"
let type : Type = MyClass.self  //Determines Type from Class
let type : Type = type(of:self) //Determines Type from self
let string : String = "\(type)" //String
doubleNum = 30.1

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

printInfo(doubleNum)
//'30.1' of type 'Double'
print("\(type(of: self)) ,\(#function)")
// within a function of a class
@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
// "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
}
print(stringType(of: SomeClass()))     // "SomeClass"
print(stringType(of: SomeClass.self))  // "SomeClass"
print(stringType(of: String()))        // "String"
print(fullStringType(of: String()))    // "Swift.String"