Difference between using ObjectIdentifier() and '===' Operator

前端 未结 1 693
感动是毒
感动是毒 2020-12-16 02:56

Let\'s say I\'m implementing a root class in Swift, which I declare adopts the Equatable protocol (I want to be able to tell if an array of my type contains a g

相关标签:
1条回答
  • 2020-12-16 03:32

    There is no difference for class instance, see the following comments in 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"
      ///
    

    It also becomes apparent from the implementation of == for ObjectIdentifier, which just compares the pointers to the object storage:

      public static func == (x: ObjectIdentifier, y: ObjectIdentifier) -> Bool {
        return Bool(Builtin.cmp_eq_RawPointer(x._value, y._value))
      }
    

    which is what the === operator does as well:

    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 conforms to Hashable, so it is useful if you want to implement that protocol for your class:

    extension MyClass: Hashable {
        var hashValue: Int {
            return ObjectIdentifier(self).hashValue
        }
    }
    

    An object identifier can also be created for meta types (e.g. ObjectIdentifier(Float.self)) for which === is not defined.

    0 讨论(0)
提交回复
热议问题