在试图理解一个程序时,或者在某些极端情况下,找出某个东西的类型是很有用的。我知道调试器可以向您显示一些类型信息,在这些情况下,您通常可以依靠类型推断来避免不指定类型,但我仍然希望有类似Python的type()的东西。

dynamicType(参见这个问题)

更新:在Swift的最新版本中,obj已被更改。dynamicType现在提供了对类型的引用,而不是动态类型的实例。

这款似乎最有希望,但到目前为止我还没能找到实际的型号。

class MyClass {
    var count = 0
}

let mc = MyClass()

# update: this now evaluates as true
mc.dynamicType === MyClass.self

我还尝试使用类引用来实例化一个新对象,这确实有效,但奇怪的是,给了我一个错误,说我必须添加一个必需的初始化器:

工作原理:

class MyClass {
    var count = 0
    required init() {
    }
}

let myClass2 = MyClass.self
let mc2 = MyClass2()

不过,要真正发现任何给定对象的类型,这仍然只是一小步

编辑:我已经删除了大量现在不相关的细节-如果你感兴趣,看看编辑历史:)


当前回答

斯威夫特2.0:

进行这种类型内省的正确方法是使用Mirror结构体,

    let stringObject:String = "testing"
    let stringArrayObject:[String] = ["one", "two"]
    let viewObject = UIView()
    let anyObject:Any = "testing"

    let stringMirror = Mirror(reflecting: stringObject)
    let stringArrayMirror = Mirror(reflecting: stringArrayObject)
    let viewMirror = Mirror(reflecting: viewObject)
    let anyMirror = Mirror(reflecting: anyObject)

然后要从镜像结构体中访问类型本身,你可以像这样使用属性subjectType:

    // Prints "String"
    print(stringMirror.subjectType)

    // Prints "Array<String>"
    print(stringArrayMirror.subjectType)

    // Prints "UIView"
    print(viewMirror.subjectType)

    // Prints "String"
    print(anyMirror.subjectType)

然后你可以这样使用:

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

其他回答

斯威夫特2.0:

进行这种类型内省的正确方法是使用Mirror结构体,

    let stringObject:String = "testing"
    let stringArrayObject:[String] = ["one", "two"]
    let viewObject = UIView()
    let anyObject:Any = "testing"

    let stringMirror = Mirror(reflecting: stringObject)
    let stringArrayMirror = Mirror(reflecting: stringArrayObject)
    let viewMirror = Mirror(reflecting: viewObject)
    let anyMirror = Mirror(reflecting: anyObject)

然后要从镜像结构体中访问类型本身,你可以像这样使用属性subjectType:

    // Prints "String"
    print(stringMirror.subjectType)

    // Prints "Array<String>"
    print(stringArrayMirror.subjectType)

    // Prints "UIView"
    print(viewMirror.subjectType)

    // Prints "String"
    print(anyMirror.subjectType)

然后你可以这样使用:

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

如果一个参数作为Any传递给你的函数,你可以测试一个特殊的类型,像这样:

   func isADate ( aValue : Any?) -> Bool{
        if (aValue as? Date) != nil {
            print ("a Date")
            return true
        }
        else {
            print ("This is not a date ")
            return false
        }
    }

dynamicType。printClassName代码来自Swift书籍中的一个示例。我不知道如何直接获取自定义类名,但可以使用is关键字检查实例类型,如下所示。这个例子还展示了如何实现一个自定义的className函数,如果你真的想要类名作为字符串。

class Shape {
    class func className() -> String {
        return "Shape"
    }
}

class Square: Shape {
    override class func className() -> String {
        return "Square"
    }
}

class Circle: Shape {
    override class func className() -> String {
        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

注意:NSObject的子类已经实现了他们自己的className函数。如果您正在使用Cocoa,您可以使用这个属性。

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

针对Swift 3.0

String(describing: <Class-Name>.self)

Swift 2.0 - 2.3

String(<Class-Name>)
//: 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")
    }
}

B.a() // yeah yeah
A.a() // yeah
B().getInnerValue() // yeah yeah
A().getInnerValue() // yeah