如何检查两个实例在swift中是相同的类/类型

Gri*_*mxn 41 swift

我知道我可以用Swift检查var的类型 is

if item is Movie {
    movieCount += 1
} else if item is Song {
    songCount += 1
}
Run Code Online (Sandbox Code Playgroud)

但是如何检查两个实例是否具有相同的类?以下不起作用:

if item1 is item2.dynamicType {
    print("Same subclass")
} else {
    print("Different subclass)
}
Run Code Online (Sandbox Code Playgroud)

我可以轻松地添加一个"类"函数并在每个子类中更新它以返回一些独特的东西,但这看起来像一个kludge ...

Ale*_*lav 45

我也回答了你如何找出一个对象的类型(在Swift中)?指出在某些时候Apple增加了===对Swift类型操作符的支持,因此以下内容现在可以工作:

if item1.dynamicType === item2.dynamicType {
    print("Same subclass")
} else {
    print("Different subclass")
}
Run Code Online (Sandbox Code Playgroud)

即使没有导入也可以工作Foundation,但请注意它只适用于类,因为structs没有动态类型.

  • `dynamicType`已被弃用.使用`type(of:...)`代替 (4认同)

T. *_*sen 38

Swift 3.0(也适用于结构)

if type(of: someInstance) == type(of: anotherInstance) {
    print("matching type")
} else {
    print("something else")
}
Run Code Online (Sandbox Code Playgroud)


hol*_*lex 29

我觉得有必要首先引用Swift编程语言文档:

类具有结构不具备的附加功能:

  • 类型转换使您可以在运行时检查和解释类实例的类型.

根据这一点,它可能对将来有所帮助:

func areTheySiblings(class1: AnyObject!, class2: AnyObject!) -> Bool {
    return object_getClassName(class1) == object_getClassName(class2)
}
Run Code Online (Sandbox Code Playgroud)

和测试:

let myArray1: Array<AnyObject> = Array()
let myArray2: Array<Int> = Array()
let myDictionary: Dictionary<String, Int> = Dictionary()
let myString: String = String()

let arrayAndArray: Bool = self.areTheySiblings(myArray1, class2: myArray2) // true
let arrayAndString: Bool = self.areTheySiblings(myArray1, class2: myString) // false
let arrayAndDictionary: Bool = self.areTheySiblings(myArray1, class2: myDictionary) // false
Run Code Online (Sandbox Code Playgroud)

UPDATE

你也可以重载一个新的运算符来做这样的事情,例如:

infix operator >!<

func >!< (object1: AnyObject!, object2: AnyObject!) -> Bool {
   return (object_getClassName(object1) == object_getClassName(object2))
}
Run Code Online (Sandbox Code Playgroud)

结果:

println("Array vs Array: \(myArray1 >!< myArray2)") // true
println("Array vs. String: \(myArray1 >!< myString)") // false
println("Array vs. Dictionary: \(myArray1 >!< myDictionary)") // false
Run Code Online (Sandbox Code Playgroud)

更新#2

你也可以将它用于你自己的新Swift类,例如:

class A { }
class B { }

let a1 = A(), a2 = A(), b = B()

println("a1 vs. a2: \(a1 >!< a2)") // true
println("a1 vs. b: \(a1 >!< b)") // false
Run Code Online (Sandbox Code Playgroud)

  • 这实际上不是"纯粹的Swift",因为`object_getClassName`是一个ObjC运行时函数.(因此,它不适用于无法桥接到ObjC类的Swift类型.) (8认同)
  • 该函数来自Objective-C运行时,因此除非你"导入Foundation"(或`import Cocoa`或`import UIKit`),否则它在Swift中不可用.它不适用于非ObjC Swift类型.这是一个很好的解决方案......只是试图缓和期望. (2认同)

and*_*ani 5

Swift 3-请注意,比较实例与检查等式是否为给定类型不同:

struct Model {}

let modelLhs = Model()
let modelRhs = Model()
type(of: modelLhs) == type(of: modelRhs) //true
type(of: modelLhs) == type(of: Model.self) //false
modelLhs is Model //true
Run Code Online (Sandbox Code Playgroud)