是否有一种方法可以在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

在上面的例子中,我正在寻找一种方法来显示变量“soon”的类型是ImplicitlyUnwrappedOptional<NSDate>,或至少NSDate!


当前回答

斯威夫特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
}

用法:

print(stringType(of: SomeClass()))     // "SomeClass"
print(stringType(of: SomeClass.self))  // "SomeClass"
print(stringType(of: String()))        // "String"
print(fullStringType(of: String()))    // "Swift.String"

其他回答

我目前的Xcode版本是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).")
    }
}

输出:

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.

我的运气是:

let className = NSStringFromClass(obj.dynamicType)

我为自己开发的类(或您可以访问的类)找到了一个解决方案。

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

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

现在你可以像这样简单地调用对象的类名:

myObject.className

请注意,只有当类定义是在与您想要的类名称完全相同的文件中创建时,这才会起作用。

因为这是常见的情况,上面的答案应该做的大多数情况下。但在某些特殊情况下,你可能需要想出一个不同的解决方案。


如果你需要类(文件)本身的类名,你可以简单地使用这一行:

let className = __FILE__.lastPathComponent.stringByDeletingPathExtension

也许这个方法能帮助到一些人。

斯威夫特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
}

用法:

print(stringType(of: SomeClass()))     // "SomeClass"
print(stringType(of: SomeClass.self))  // "SomeClass"
print(stringType(of: String()))        // "String"
print(fullStringType(of: String()))    // "Swift.String"

上面的答案没有使用type(of:的新方法的工作示例。所以为了帮助像我这样的新手,这里有一个工作的例子,主要来自苹果的文档- 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'