使用和等于
有三个相等运算符:==
,===
和 isequal
。 (最后一个不是真正的运算符,但它是一个函数,所有运算符都是函数。)
什么时候使用 ==
==
是价值相等。当两个对象在其当前状态下表示相同的值时,它返回 true
。
例如,很明显
julia> 1 == 1
true
但此外
julia> 1 == 1.0
true
julia> 1 == 1.0 + 0.0im
true
julia> 1 == 1//1
true
上面每个相等的右边是不同的类型 ,但它们仍然代表相同的值。
对于可变对象,如数组 ,==
比较它们的现值。
julia> A = [1, 2, 3]
3-element Array{Int64,1}:
1
2
3
julia> B = [1, 2, 3]
3-element Array{Int64,1}:
1
2
3
julia> C = [1, 3, 2]
3-element Array{Int64,1}:
1
3
2
julia> A == B
true
julia> A == C
false
julia> A[2], A[3] = A[3], A[2] # swap 2nd and 3rd elements of A
(3,2)
julia> A
3-element Array{Int64,1}:
1
3
2
julia> A == B
false
julia> A == C
true
大多数时候,==
是正确的选择。
什么时候使用 ===
===
比 ==
更严格的操作。它不是价值相等,而是衡量价值。如果两个对象无法通过程序本身彼此区分,则它们是相等的。因此我们有
julia> 1 === 1
true
因为没有办法告诉 1
除了另一个 1
。但
julia> 1 === 1.0
false
因为尽管 1
和 1.0
是相同的值,但它们的类型不同,因此程序可以区分它们。
此外,
julia> A = [1, 2, 3]
3-element Array{Int64,1}:
1
2
3
julia> B = [1, 2, 3]
3-element Array{Int64,1}:
1
2
3
julia> A === B
false
julia> A === A
true
这可能起初看起来令人惊讶! 该程序如何区分两个向量 A
和 B
?因为向量是可变的,它可以修改 A
,然后它的行为与 B
不同。但无论它如何修改 A
,A
将始终与 A
本身相同。因此,A
对于 A
来说是天生的,但对于 B
来说并不是真的。
继续沿着这个脉络,观察
julia> C = A
3-element Array{Int64,1}:
1
2
3
julia> A === C
true
通过将 A
分配给 C
,我们说 C
已经别名 A
。也就是说,它已成为 A
的另一个名称。对 A
所做的任何修改也将由 C
观察到。因此,没有办法区分 A
和 C
之间的区别,因此它们是相等的。
什么时候使用 isequal
==
和 isequal
之间的区别非常微妙。最大的区别在于如何处理浮点数:
julia> NaN == NaN
false
这可能令人惊奇的结果是限定由用于浮点类型(IEEE-754)的 IEEE 标准。但是在某些情况下这没有用,例如排序。isequal
是为这些情况提供的:
julia> isequal(NaN, NaN)
true
在光谱的另一面,==
将 IEEE 负零和正零视为相同的值(也是 IEEE-754 规定的)。然而,这些值在存储器中具有不同的表示。
julia> 0.0
0.0
julia> -0.0
-0.0
julia> 0.0 == -0.0
true
再次出于分类目的,isequal
区分它们。
julia> isequal(0.0, -0.0)
false