==和===之间的区别

在swift中似乎有两个等号运算符:double等于( == )和triple等于( === ),两者有什么区别?

!=====是身份运算符,用于确定两个对象是否具有相同的引用。

Swift还提供了两个身份运算符(===和!==),用于testing两个对象引用是否都引用同一个对象实例。

摘录自:苹果公司“Swift编程语言”,iBooks。 https://itun.es/us/jEUH0.l

在Objective-C和Swift中, ==!=运算符为数值(例如NSIntegerNSUInteger ,Objective-C和Int NSNumber ,Swift中的UInt等等)testing值是否相等。 对于Objective-C中的对象(NSObject和子类)和Swift中的引用types, ==!=testing对象/引用types是相同的东西 – 即相同的散列值 – 或者不是相同的东西, 分别。

 let a = NSObject() let b = NSObject() let c = a a == b // false a == c // true 

Swift的身份相等运算符===!==检查引用相等性 – 因此可能被称为引用相等运算符IMO。

 a === b // false a === c // true 

另外值得指出的是,Swift中的自定义引用types(不符合Equatable类的子类)不会自动实现等于运算符,但是等号运算符仍然适用。 另外,通过执行==!=会自动执行。

 class MyClass: Equatable { let myProperty: String init(s: String) { myProperty = s } } func ==(lhs: MyClass, rhs: MyClass) -> Bool { return lhs.myProperty == rhs.myProperty } let myClass1 = MyClass(s: "Hello") let myClass2 = MyClass(s: "Hello") myClass1 == myClass2 // true myClass1 != myClass2 // false myClass1 === myClass2 // false myClass1 !== myClass2 // true 

这些平等运算符并不适用于其他任何types的语言结构types。 但是,自定义运算符可以在Swift中创build,例如,您可以创build一个运算符来检查CGPoint的相等性。

 infix operator <==> { precedence 130 } func <==> (lhs: CGPoint, rhs: CGPoint) -> Bool { return lhs.x == rhs.x && lhs.y == rhs.y } let point1 = CGPoint(x: 1.0, y: 1.0) let point2 = CGPoint(x: 1.0, y: 1.0) point1 <==> point2 // true 

Swifts ===有一些微妙之处,超越了单纯的指针algorithm。 而在Objective-C中,你可以将任何两个指针(即NSObject * )与==进行比较,这在Swift中不再是真实的,因为types在编译过程中发挥了更大的作用。

一个游乐场会给你

 1 === 2 // false 1 === 1 // true let one = 1 // 1 1 === one // compile error: Type 'Int' does not conform to protocol 'AnyObject' 1 === (one as AnyObject) // true (surprisingly (to me at least)) 

用string,我们将不得不习惯这个:

 var st = "123" // "123" var ns = (st as NSString) // "123" st == ns // true, content equality st === ns // compile error ns === (st as NSString) // false, new struct ns === (st as AnyObject) // false, new struct (st as NSString) === (st as NSString) // false, new structs, bridging is not "free" (as in "lunch") NSString(string:st) === NSString(string:st) // false, new structs var st1 = NSString(string:st) // "123" var st2 = st1 // "123" st1 === st2 // true var st3 = (st as NSString) // "123" st1 === st3 // false (st as AnyObject) === (st as AnyObject) // false 

但是你也可以玩得开心,如下所示:

 var st4 = st // "123" st4 == st // true st4 += "5" // "1235" st4 == st // false, not quite a reference, copy on write semantics 

我相信你可以想到更多有趣的案例:-)

Swift 3的更新 (正如JakubTruhlář的评论所build议的那样)

 1===2 // Compiler error: binary operator '===' cannot be applied to two 'Int' operands (1 as AnyObject) === (2 as AnyObject) // false let two = 2 (2 as AnyObject) === (two as AnyObject) // false (rather unpleasant) (2 as AnyObject) === (2 as AnyObject) // false (this makes it clear that there are new objects being generated) 

这看起来更符合Type 'Int' does not conform to protocol 'AnyObject' ,然而我们然后得到

 type(of:(1 as AnyObject)) // _SwiftTypePreservingNSNumber.Type 

但明确的转换表明可能会有某些事情正在进行。 在事物的String方面,只要我们import CocoaNSString仍然可用。 那我们就会有

 var st = "123" // "123" var ns = (st as NSString) // "123" st == ns // Compile error with Fixit: 'NSString' is not implicitly convertible to 'String'; did you mean to use 'as' to explicitly convert? st == ns as String // true, content equality st === ns // compile error: binary operator '===' cannot be applied to operands of type 'String' and 'NSString' ns === (st as NSString) // false, new struct ns === (st as AnyObject) // false, new struct (st as NSString) === (st as NSString) // false, new structs, bridging is not "free" (as in "lunch") NSString(string:st) === NSString(string:st) // false, new objects var st1 = NSString(string:st) // "123" var st2 = st1 // "123" st1 === st2 // true var st3 = (st as NSString) // "123" st1 === st3 // false (st as AnyObject) === (st as AnyObject) // false 

有两个String类仍然令人困惑,但是放弃隐式转换可能会使它更容易被察觉。

在迅速3

=== (或!==

  • 检查值是否相同。
  • 比较参考types。
  • 在Obj-C(指针相等)中像==

== (或!=

  • 检查值是否相同。
  • 比较值types
  • isEqual:在Obj-C中(但是,您可以在Obj-C中重写isEqual )。

这里我比较三个实例(类是一个引用types)

 class Person { } let person = Person() let person2 = person let person3 = Person() person === person2 // true person === person3 // false 

例如,如果你创build了一个类的两个实例,例如myClass

 var inst1 = myClass() var inst2 = myClass() 

你可以比较这些实例,

 if inst1 === inst2 

引用:

您可以使用它来testing两个对象引用是否都引用同一个对象实例。

摘录自:苹果公司“Swift编程语言”,iBooks。 https://itun.es/sk/jEUH0.l

在Swift中我们有=== simbol这意味着两个对象都指的是同一个引用相同的地址

 class SomeClass { var a: Int; init(_ a: Int) { self.a = a } } var someClass1 = SomeClass(4) var someClass2 = SomeClass(4) someClass1 === someClass2 // false someClass2 = someClass1 someClass1 === someClass2 // true 

只是一个小任务有关的Any对象。

我正在使用NotificationCenter进行unit testing,它使用Any作为我想比较的参数。

但是,由于Any不能用于平等操作,所以有必要改变它。 最终,我决定采取以下方法,这使我能够在我的具体情况下获得平等,这里以一个简单的例子显示:

 func compareTwoAny(a: Any, b: Any) -> Bool { return ObjectIdentifier(a as AnyObject) == ObjectIdentifier(b as AnyObject) } 

这个函数利用ObjectIdentifier ,它为对象提供了一个唯一的地址,允许我testing。

在上面的链接中,关于每个苹果的ObjectIdentifier ,需要注意的一点是:

在Swift中,只有类实例和元types具有唯一的标识。 结构,枚举,函数或元组没有标识的概念。

(==)将检查是否都具有相同的值,如果(a == b){//值}

但(===)将检查值以及这些variables的types,如果相同或不。 如果(a === b){//值和数据types}

谢谢,