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

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

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


当前回答

以下是我推荐的两种方法:

if let thisShape = aShape as? Square 

Or:

aShape.isKindOfClass(Square)

下面是一个详细的例子:

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")
}

其他回答

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

老问题,但这符合我的需要(Swift 5.x):

print(type(of: myObjectName))

针对Swift 3.0

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

Swift 2.0 - 2.3

String(<Class-Name>)

从Xcode 6.0.1开始(至少,不确定他们什么时候添加的),你原来的例子现在可以工作了:

class MyClass {
    var count = 0
}

let mc = MyClass()
mc.dynamicType === MyClass.self // returns `true`

更新:

要回答最初的问题,您实际上可以成功地将Objective-C运行时与普通Swift对象一起使用。

试试下面的方法:

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
String.fromCString(class_getName(m2.dynamicType))
String.fromCString(object_getClassName(m2))
// Returns .Some("__lldb_expr_42.MyClass")
String.fromCString(object_getClassName(mc))

这取决于用例。但是让我们假设您想要对“变量”类型做一些有用的事情。Swift switch语句非常强大,可以帮助你得到你想要的结果…

    let dd2 = ["x" : 9, "y" : "home9"]
    let dds = dd2.filter {
        let eIndex = "x"
        let eValue:Any = 9
        var r = false

        switch eValue {
        case let testString as String:
            r = $1 == testString
        case let testUInt as UInt:
            r = $1 == testUInt
        case let testInt as Int:
            r = $1 == testInt
        default:
            r = false
        }

        return r && $0 == eIndex
    }

在这种情况下,有一个简单的字典,其中包含键/值对,可以是UInt, Int或String。在字典上的.filter()方法中,我需要确保正确地测试值,并且只在字符串时测试字符串,等等。switch语句使此操作简单而安全! 通过将9赋值给Any类型的变量,它将执行Int类型的转换。试着把它改成:

   let eValue:Any = "home9"

..再试一次。这一次,它执行了as String的情况。