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

时间:2014-06-11 11:19:22

标签: swift

我知道我可以使用is

检查Swift中var的类型
if item is Movie {
    movieCount += 1
} else if item is Song {
    songCount += 1
}

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

if item1 is item2.dynamicType {
    print("Same subclass")
} else {
    print("Different subclass)
}

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

8 个答案:

答案 0 :(得分:45)

我还回答How do you find out the type of an object (in Swift)?指出,在某些时候,Apple为===运算符添加了对Swift类型的支持,因此以下内容现在可以使用:

if item1.dynamicType === item2.dynamicType {
    print("Same subclass")
} else {
    print("Different subclass")
}

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

答案 1 :(得分:35)

Swift 3.0(也适用于结构)

if type(of: someInstance) == type(of: anotherInstance) {
    print("matching type")
} else {
    print("something else")
}

答案 2 :(得分:28)

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

  

类具有结构不的其他功能:

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

根据这一点,它可能对未来的某些人有所帮助:

func areTheySiblings(class1: AnyObject!, class2: AnyObject!) -> Bool {
    return object_getClassName(class1) == object_getClassName(class2)
}

和测试:

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

更新

你也可以为一个新的操作符重载这样的事情,例如这样:

infix operator >!<

func >!< (object1: AnyObject!, object2: AnyObject!) -> Bool {
   return (object_getClassName(object1) == object_getClassName(object2))
}

和结果:

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

更新#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

答案 3 :(得分:4)

斯威夫特3 - 注意比较实例与检查istance是否属于给定类型不同:

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

答案 4 :(得分:1)

我正在使用它,对我有帮助: 仅当所有对象都是相同类型时,它才返回true

func areObjects<T>(_ objects: [Any], ofType: T.Type) -> Bool {
    for object in objects {
        if !(object is T) {
            return false
        }
    }
    return true
}

答案 5 :(得分:1)

在Swift 5中,如果值之一是“ self”,则可以使用“ Self”类型来测试一个值是否与另一类型相同。可以在结构中使用,如下所示。

(我实际上是在这里寻找一种无需Self的方法,因为我正在尝试重构某些东西。上面提到的'type(of:ship)'方法看起来像是最普通的方法。我有测试了它是否与下面的示例兼容。)

protocol Ship { var name: String {get} }

extension Ship {
    func isSameClass(as other: Ship) -> Bool {
        return other is Self
    }
}

struct Firefly: Ship { var name: String }
struct Trebuchet: Ship { var name: String }

func speak(about s1: Ship, and s2: Ship) {
    print(  "\(s1.name) and \(s2.name) are "
        +   "\(s1.isSameClass(as: s2) ? "" : "not ")"
        +   "the same class." )
}

func talk(about s1: Ship, and s2: Ship) {
    print(  "\(s1.name) and \(s2.name) are "
        +   "\(type(of: s1) == type(of: s2) ? "" : "not ")"
        +   "the same class." )
}

var serenity = Firefly(name: "Serenity")
var saffron = Firefly(name: "Saffron")
var inara = Trebuchet(name: "Inara")

speak(about: serenity, and: saffron)    // Serenity and Saffron are the same class.
speak(about: serenity, and: inara)      // Serenity and Inara are not the same class.
talk(about: serenity, and: saffron)     // Serenity and Saffron are the same class.
talk(about: serenity, and: inara)       // Serenity and Inara are not the same class.

答案 6 :(得分:0)

目前,Swift类型没有内省,因此没有内置方法来获取实例的类型。 instance.className适用于Objc课程。

答案 7 :(得分:0)

对于NSObject的子类,我去了:

let sameClass: Bool = instance1.classForCoder == instance2.classForCoder

此方法的另一个警告,

  

在归档时,类集群的私有子类将替换其公共超类的名称。

Apple documentation