“与”的区别是什么==&引用;及===&引用;Julia中的比较运算符?
Julia中的比较运算符与“与”的区别是什么==&引用;及===&引用;Julia中的比较运算符?,julia,Julia,Julia中的比较运算符与==之间有什么区别?==意味着它实际上是同一个对象,即变量指向内存中的同一点=表示对象具有相同的值。例如: julia> A = rand(5,5) #Make an array 5x5 Array{Float64,2}: 0.349193 0.408216 0.703084 0.163128 0.815687 0.211441 0.0185634 0.378299 0.0734293 0.187445 0.667637 0.13932
==
之间有什么区别?==
意味着它实际上是同一个对象,即变量指向内存中的同一点<代码>=表示对象具有相同的值。例如:
julia> A = rand(5,5) #Make an array
5x5 Array{Float64,2}:
0.349193 0.408216 0.703084 0.163128 0.815687
0.211441 0.0185634 0.378299 0.0734293 0.187445
0.667637 0.139323 0.286794 0.359962 0.229784
0.476224 0.49812 0.648244 0.831006 0.1787
0.960756 0.488886 0.195973 0.148958 0.200619
julia> B = A # This sets the pointer of B to the pointer of A
5x5 Array{Float64,2}:
0.349193 0.408216 0.703084 0.163128 0.815687
0.211441 0.0185634 0.378299 0.0734293 0.187445
0.667637 0.139323 0.286794 0.359962 0.229784
0.476224 0.49812 0.648244 0.831006 0.1787
0.960756 0.488886 0.195973 0.148958 0.200619
julia> B === A # Same spot in memory
true
julia> B[1,1]=2 #Change a value of B
2
julia> B
5x5 Array{Float64,2}:
2.0 0.408216 0.703084 0.163128 0.815687
0.211441 0.0185634 0.378299 0.0734293 0.187445
0.667637 0.139323 0.286794 0.359962 0.229784
0.476224 0.49812 0.648244 0.831006 0.1787
0.960756 0.488886 0.195973 0.148958 0.200619
julia> A #Also changes A since they point to the same spot
5x5 Array{Float64,2}:
2.0 0.408216 0.703084 0.163128 0.815687
0.211441 0.0185634 0.378299 0.0734293 0.187445
0.667637 0.139323 0.286794 0.359962 0.229784
0.476224 0.49812 0.648244 0.831006 0.1787
0.960756 0.488886 0.195973 0.148958 0.200619
julia> B = copy(A) #Now make B a copy of A, no longer the same pointer
5x5 Array{Float64,2}:
2.0 0.408216 0.703084 0.163128 0.815687
0.211441 0.0185634 0.378299 0.0734293 0.187445
0.667637 0.139323 0.286794 0.359962 0.229784
0.476224 0.49812 0.648244 0.831006 0.1787
0.960756 0.488886 0.195973 0.148958 0.200619
julia> B === A # Now this is false
false
julia> B == A # This is still true
true
julia> B[1,1] = 1 #Changing B
1
julia> B
5x5 Array{Float64,2}:
1.0 0.408216 0.703084 0.163128 0.815687
0.211441 0.0185634 0.378299 0.0734293 0.187445
0.667637 0.139323 0.286794 0.359962 0.229784
0.476224 0.49812 0.648244 0.831006 0.1787
0.960756 0.488886 0.195973 0.148958 0.200619
julia> A #Now does not change A
5x5 Array{Float64,2}:
2.0 0.408216 0.703084 0.163128 0.815687
0.211441 0.0185634 0.378299 0.0734293 0.187445
0.667637 0.139323 0.286794 0.359962 0.229784
0.476224 0.49812 0.648244 0.831006 0.1787
0.960756 0.488886 0.195973 0.148958 0.200619
@Chrisrackaukas的答案就其本身而言是准确的——即对于可变对象。然而,问题还不止于此,所以我将在这里详细阐述一下
==
运算符(函数的别名)实现了Henry Baker的EGAL谓词[,]:x===y
在两个对象在编程上无法区分时为真–即,您无法编写显示x
和y
之间任何差异的代码。这归结为以下规则:
- 对于可变值(数组、可变复合类型),
检查对象标识:==
如果x===y
和x
是存储在内存中相同位置的相同对象,则为truey
- 对于不可变的复合类型,
如果x===y
和x
具有相同的类型–因此具有相同的结构–并且它们对应的组件都是递归的y
,则==
为真x==y
- 对于位类型(不可变的数据块,如
或Int
),如果Float64
和x
包含完全相同的位,则y
为真x===y
=
的行为
另一方面,=
函数可由用户定义,并实现“抽象值相等”。过载能力是一个关键区别:
不可重载–它是一个具有固定预定义行为的内置函数。不能扩展或更改其行为==
是可重载的–它是一个具有中缀语法的普通(对于Julia)通用函数。它具有回退定义,为用户定义的类型提供了有用的默认行为,但您可以通过向类型的=
添加新的、更具体的方法来改变这一点==
==
行为以及扩展用户定义类型时用户定义类型的行为的更多详细信息,请访问:
例如,所有数值类型都按数值进行比较,忽略
类型。字符串作为字符序列进行比较,忽略
编码
你可以认为这是“直觉上的平等”。如果两个数字在数字上相等,则它们是==
:
julia> 1 == 1.0 == 1 + 0im == 1.0 + 0.0im == 1//1
true
julia> 0.5 == 1/2 == 1//2
true
但是请注意,=
实现了精确的数字相等:
julia> 2/3 == 2//3
false
这些值是不相等的,因为2/3
是浮点值0.666666
,它是最接近数学值2/3的Float64
(或者在有理值的Julia表示法中,2//3
),但0.666666
并不完全等于2/3。而且,==
浮点数遵循IEEE 754语义
这包括一些可能意外的属性:
- 有不同的正浮点零和负浮点零(
和0.0
):它们是-0.0
,尽管它们的行为不同,因此不是=
=
- 有许多不同的not-a-number(
)值:它们不是NaN
本身、彼此或任何其他值;它们各自是自己的==
,但不是==
==因为它们有不同的位,所以代码>会相互转换
julia> 0.0 === -0.0
false
julia> 0.0 == -0.0
true
julia> 1/0.0
Inf
julia> 1/-0.0
-Inf
julia> NaN === NaN
true
julia> NaN === -NaN
false
julia> -NaN === -NaN
true
julia> NaN == NaN
false
julia> NaN == -NaN
false
julia> NaN == 1.0
false
这有点令人困惑,但这是IEEE标准
此外,==
的文档还说明:
集合通常应该通过递归调用所有内容来实现==
因此,=
给出的值相等的概念被递归地扩展到集合:
julia> [1, 2, 3] == [1, 2, 3]
true
julia> [1, 2, 3] == [1.0, 2.0, 3.0]
true
julia> [1, 2, 3] == Any[1//1, 2.0, 3 + 0im]
true
因此,这继承了标量比较的缺点:
julia> a = [1, NaN, 3]
3-element Array{Float64,1}:
1.0
NaN
3.0
julia> a == a
false
另一方面,==
比较始终测试对象标识,因此即使两个数组具有相同的类型并包含相同的值,但只有在它们是相同的数组时,它们才是相等的:
julia> b = copy(a)
3-element Array{Float64,1}:
1.0
NaN
3.0
julia> a === a
true
julia> a === b
false
julia> b === b
true
a
和b
不是==
的原因是,尽管它们当前恰好包含相同的数据,但由于它们是可变的且不是相同的对象,您可以对其中一个进行变异,然后很明显它们是不同的:
julia> a[1] = -1
-1
julia> a # different than before
3-element Array{Int64,1}:
-1
2
3
julia> b # still the same as before
3-element Array{Int64,1}:
1
2
3
因此,通过变异,你可以看出a
和b
是不同的对象。同样的逻辑不适用于不可变对象:如果它们包含相同的数据,则只要它们具有相同的值,就无法区分。因此,不可变值从绑定到特定位置的数据中解放出来,这也是编译器能够如此有效地优化不可变值使用的原因之一
另请参见:
Base==代码>但搜索结果为零。如果我猜==
将在基本函数中,我是对的,但我只看到它在操作顺序中的位置。最后,通过谷歌搜索“三重相等”,我发现了这个问题(这是很好的答案!