在swift中似乎有两个相等运算符:双相等(==
)和三相等(===
),这两者有什么区别?
在Objective-C和Swift中,==
和!=
运算符测试数值的值相等性(例如,Objective-C中的nsinteger
、nsuinteger
、int
和Swift中的int
、uint
等)。对于对象(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
!==
和===
是标识运算符,用于确定两个对象是否具有相同的引用。
Swift还提供了两个标识运算符(===和!==),您可以使用它们来测试两个对象引用是否都引用了同一个对象实例。
摘自:苹果公司,“快速编程语言”,iBooks。https://itun.es/us/jeuh0.l
简而言之:
==
运算符检查它们的实例值是否相等,“等于”
===
运算符检查引用是否指向同一实例,“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直接将比较做错了。请为我解释。 问题答案: 而在技术上两个不同的对象和运营商只比较引用。 更好,因为它比较值而不是引用。但是仍然不理想。直接比较浮点值应始终将一些误差(ε)考虑在内()。 注意: 这里的比较会产生,但是比较复杂(内部缓存