Как проверить два экземпляра - это тот же класс/тип в swift

Я знаю, что я могу проверить тип var в Swift с помощью is

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...

Ответ 1

В первую очередь мне необходимо процитировать из документации Swift Programming Language:

У классов есть дополнительные возможности, которые структуры не:

  • Тип casting позволяет вам проверять и интерпретировать тип экземпляра класса во время выполнения.

В соответствии с этим, это может быть полезно для кого-то в будущем:

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

UPDATE

вы также можете перегрузить новый оператор для выполнения таких действий, например, например. это:

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

UPDATE # 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

Ответ 2

Я также ответил Как узнать тип объекта (в Swift)?, чтобы указать, что в какой-то момент Apple добавила поддержку === оператора для типов Swift, поэтому теперь будут работать следующие команды:

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

Это работает даже без импорта Foundation, но обратите внимание, что он будет работать только для классов, так как structs не имеет динамического типа.

Ответ 3

Swift 3.0 (также работает с структурами)

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

Ответ 4

В настоящее время типы Swift не имеют интроспекции, поэтому нет встроенного способа получения типа экземпляра. instance.className работает для классов Objc.

Ответ 5

Свифт 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