当前位置: 首页 > 知识库问答 >
问题:

==与===之间的差异

阎丰羽
2023-03-14

在swift中似乎有两个相等运算符:双相等(==)和三相等(===),这两者有什么区别?

共有3个答案

魏景龙
2023-03-14

在Objective-C和Swift中,==!=运算符测试数值的值相等性(例如,Objective-C中的nsintegernsuintegerint和Swift中的intuint等)。对于对象(Objective-C中的nsobject/nsnumber和子类以及Swift中的引用类型),=!=分别测试对象/引用类型是否是相同的东西(即,相同的散列值),或者不是相同的东西。

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

Swift的标识等式运算符===!==检查引用等式--因此,可能应该称为引用等式运算符IMO。

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

还值得指出的是,Swift中的自定义引用类型(不对符合Equatable的类进行子类划分)不会自动实现equal to运算符,但identity equal运算符仍然适用。此外,通过实现==!=将自动实现。

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

这些等式运算符不会为其他类型(如两种语言中的结构)实现。但是,可以在Swift中创建自定义运算符,例如,这将使您能够创建一个运算符来检查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
刘和玉
2023-03-14

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

Swift还提供了两个标识运算符(===和!==),您可以使用它们来测试两个对象引用是否都引用了同一个对象实例。

摘自:苹果公司,“快速编程语言”,iBooks。https://itun.es/us/jeuh0.l

岳彬炳
2023-03-14

简而言之:

==运算符检查它们的实例值是否相等,“等于”

===运算符检查引用是否指向同一实例,“imagenous to”

长长的回答:

类是引用类型,多个常量和变量可以在后台引用同一个类的单个实例。类引用停留在运行时堆栈(RTS)中,它们的实例停留在内存的堆区域中。当您使用==控制相等时,它意味着它们的实例是否彼此相等。它不需要是相同的实例才能相等。为此,您需要为自定义类提供相等条件。默认情况下,自定义类和结构不接收等价运算符(称为“等于”运算符==和“不等于”运算符!=)的默认实现。为此,自定义类需要符合equatable协议及其静态函数==(lhs:,rhs:)->bool函数

让我们看看示例:

class Person : Equatable {
    let ssn: Int
    let name: String

    init(ssn: Int, name: String) {
        self.ssn = ssn
        self.name = name
    }

    static func == (lhs: Person, rhs: Person) -> Bool {
        return lhs.ssn == rhs.ssn
    }
}

附注:由于ssn(社会安全号码)是唯一的号码,因此您不需要比较它们的名称是否相等。

let person1 = Person(ssn: 5, name: "Bob")
let person2 = Person(ssn: 5, name: "Bob")

if person1 == person2 {
   print("the two instances are equal!")
}

虽然person1和person2引用在堆区域中指向两个不同的实例,但它们的实例是相等的,因为它们的ssn编号相等。因此输出将是这两个实例是相等的!

if person1 === person2 {
   //It does not enter here
} else {
   print("the two instances are not identical!")
}

===运算符检查引用是否指向同一实例,“imagenous to”。由于person1和person2在堆区域中有两个不同的实例,因此它们不相同,输出这两个实例不相同!

let person3 = person1

p.s:类是引用类型,Person1的引用通过此html" target="_blank">赋值操作复制到person3,因此两个引用都指向堆区域中的同一个实例。

if person3 === person1 {
   print("the two instances are identical!")
}

它们是相同的,输出将是这两个实例是相同的!

 类似资料:
  • 嗨,我对时区没有什么疑问: null 我在维基百科和许多相关网站上搜索过,但没有找到相关的解释

  • 什么时候只能使用其中的一个? 何时可以同时使用和如何选择一个?

  • 方法接受一个供应商函数接口,该接口本质上不接受任何参数,并返回。 在哪种情况下需要使用?如果您有一个方法为什么不直接执行而不执行? 似乎并不是要将lambda表达式的执行推迟到以后的某个时间或其他时间,那么这有什么意义呢?(我认为如果它返回一个更安全的会更有用,它的从不抛出并且总是返回true...但显然它不是,它只是返回,就像)。 是不是还有什么我遗漏的不同之处?

  • 我正在使用LWJGL3学习ThinMatrix的Opengl教程。代码中有很多和。他们是什么意思?这些是不同的opengl版本吗?以及为什么其中一些包含另一个对象没有的字段。与一样,GL15有字段,而没有,尽管它看起来是在之后。

  • 问题内容: 我知道这是一个包装类,它包装数字。今天,我看到了另一个主要区别: 我真奇怪! 因此,如果每次使用,我们都必须执行以下操作: 我无法解释为什么Double直接将比较做错了。请为我解释。 问题答案: 而在技术上两个不同的对象和运营商只比较引用。 更好,因为它比较值而不是引用。但是仍然不理想。直接比较浮点值应始终将一些误差(ε)考虑在内()。 注意: 这里的比较会产生,但是比较复杂(内部缓存