假设我正在Swift中实现一个根类,我声明该根类采用了Equatable协议(我希望能够知道我类型的数组是否包含给定的实例)。
Equatable
*在此特定情况下,将协议的所需==运算符实现为之间有 *什么区别( 如果有的话):
==
public static func ==(lhs: MyClass, rhs: MyClass) -> Bool { return ObjectIdentifier(lhs) == ObjectIdentifier(rhs) }
…而不是仅仅这样做:
public static func ==(lhs: MyClass, rhs: MyClass) -> Bool { return (lhs === rhs) }
作为参考,这是文档中所说的ObjectIdentifier():
ObjectIdentifier()
类实例或元类型的唯一标识符。在Swift中,只有类实例和元类型才具有唯一标识。对于结构,枚举,函数或元组,没有身份的概念。
......这是什么的“基本算法”一节雨燕编程语言(斯威夫特3)表示,有关===操作:
===
注意 Swift还提供了两个标识运算符(===和!==),用于测试两个对象引用是否都引用同一对象实例。有关更多信息,请参见类和结构。
注意
Swift还提供了两个标识运算符(===和!==),用于测试两个对象引用是否都引用同一对象实例。有关更多信息,请参见类和结构。
!==
类实例没有区别,请参见ObjectIdentifier.swift中的以下 注释:
/// Creates an instance that uniquely identifies the given class instance. /// /// The following example creates an example class `A` and compares instances /// of the class using their object identifiers and the identical-to /// operator (`===`): /// /// class IntegerRef { /// let value: Int /// init(_ value: Int) { /// self.value = value /// } /// } /// /// let x = IntegerRef(10) /// let y = x /// /// print(ObjectIdentifier(x) == ObjectIdentifier(y)) /// // Prints "true" /// print(x === y) /// // Prints "true" /// /// let z = IntegerRef(10) /// print(ObjectIdentifier(x) == ObjectIdentifier(z)) /// // Prints "false" /// print(x === z) /// // Prints "false" ///
从for的实现中==``ObjectIdentifier也可以明显看出,该 实现只比较指向对象存储的指针:
==``ObjectIdentifier
public static func == (x: ObjectIdentifier, y: ObjectIdentifier) -> Bool { return Bool(Builtin.cmp_eq_RawPointer(x._value, y._value)) }
这正是该===操作 确实还有:
public func === (lhs: AnyObject?, rhs: AnyObject?) -> Bool { switch (lhs, rhs) { case let (l?, r?): return Bool(Builtin.cmp_eq_RawPointer( Builtin.bridgeToRawPointer(Builtin.castToUnknownObject(l)), Builtin.bridgeToRawPointer(Builtin.castToUnknownObject(r)) )) case (nil, nil): return true default: return false } }
ObjectIdentifier符合Hashable,因此如果要为您的类实现该协议,将非常有用:
ObjectIdentifier
Hashable
extension MyClass: Hashable { var hashValue: Int { return ObjectIdentifier(self).hashValue } }
还可以为未定义的元类型(例如ObjectIdentifier(Float.self))创建对象标识符===。
ObjectIdentifier(Float.self)