2016-09-20 21 views
6

Arasındaki Fark, Swift'de bir kök sınıf uygulayayım diyelim ki, Equatable protokolünü kabul ettiğimi bildiriyorum (türümün bir dizisinin içerip içermediğini anlamak istiyorum) belirli bir örnek veya değil). olarak protokolün gerektirdiği == operatörü uygulanması arasındaki bu özel vakadan- içinde, herhangi -eğer farkı nedirObjectIdentifier() ve '===' Kullanıcısı Operatör

:

public static func ==(lhs: MyClass, rhs: MyClass) -> Bool { 

    return ObjectIdentifier(lhs) == ObjectIdentifier(rhs) 
} 

... aksine sadece bunu yapmaya:

public static func ==(lhs: MyClass, rhs: MyClass) -> Bool { 

    return (lhs === rhs) 
} 
Bir başvuru olarak, belgenin ObjectIdentifier()::

sınıf örneği veya metatype için benzersiz bir tanımlayıcı. Swift'de yalnızca sınıf örnekleri ve metatiplerin benzersiz kimlikleri vardır. Yapılar, sayılar, işlevler veya kopyalar için kimlik kavramı yoktur.

... ve bu The Swift Programming Language (Swift 3) "Temel Operatörleri" bölümü === operatör için söyledikleridir:

Swift ayrıca iki kimlik operatörleri (=== ve !==) içerir

NOT, iki nesne başvurusunun her ikisinin de aynı nesne örneğine başvurup başvurmadığını test etmek için kullandığınız. Daha fazla bilgi için bkz. Sınıflar ve Yapılar. sınıf örneği bir fark yoktur

cevap

8

, bakınız, aşağıdaki 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" 
    /// 

Aynı zamanda sadece amacı ise, saklama için işaretçiler karşılaştırır implementation of == for ObjectIdentifier, aşikar hale:

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

olduğu hangi yanı es:

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

ObjectIdentifierHashable uygundur, böylece sınıf için o protokolünü uygulamak istiyorsanız bu yararlıdır:

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

bir nesne tanımlayıcısı da meta türleri için oluşturulabilir (Örneğin) === için tanımlanmamıştır.

+0

Çok detaylı yanıt için teşekkür ederiz. Kendi sınıflarım için büyük bir fark beklemiyordum, ama bu çok aydınlatıcı. Kaynak kodunu kontrol etmeyi düşünmeliydim, şimdi Swift açık kaynak! –

+1

'===' operatör [şimdi doğrudan karşılaştırır] (https://github.com/apple/swift/blob/b330c6078fd233ea7206158a20b21b4672d75cc3/stdlib/public/core/Equatable.swift#L249) 'ObjectIdentifier 'parametrelerinin. – execv