使用和等于

有三个相等运算符:=====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

因为尽管 11.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

这可能起初看起来令人惊讶! 该程序如何区分两个向量 AB?因为向量是可变的,它可以修改 A,然后它的行为与 B 不同。但无论它如何修改 AA 将始终与 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 观察到。因此,没有办法区分 AC 之间的区别,因此它们是相等的。

什么时候使用 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