2016-07-26 9 views
2

Juliaの比較演算子=====の違いは何ですか?Juliaの "=="と "==="比較演算子の違いは何ですか?

+0

フム。 JuliaサイトでJulia lang docsを検索すると、Googleで検索を開始した約30秒以内にドキュメントにアクセスして検索することができました。 –

+0

http://docs.julialang.org/en/release-0.4/stdlib/base/#all-objects –

+0

あなたが従っていないドキュメントが何であるかを明確にすると、役立つでしょう。 –

答えて

7

===は、変数が実際には同じオブジェクトであること、つまり変数がメモリ内の同じ場所を指していることを意味します。 ==は、オブジェクトが同じ値を持つことを意味します。例:

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 
+4

また、1) '=='はオーバーロード可能ですが、 '==='はそうではありません。 2) '==='は 'immutable'オブジェクトをその内容で比較します。考え方は 'x === y'は' x'と 'y'を区別する方法がない場合にのみ真でなければならないということです。これはegal述語とも呼ばれます。 –

6

@ ChrisRackauckasの回答は、変更可能なオブジェクト、つまり変更可能なオブジェクトについては正確です。しかしそれよりももう少し問題があるので、ここで少し詳しく説明します。

===オペレータ(is関数のエイリアス)21]ヘンリー・ベイカーのEGAL述語を実装する2つのオブジェクトは、プログラム区別できない場合x === yが真である - すなわち、もしxyとの間の差を示すコードを記述することができません。これは、次のルールに要約:可変値(アレイ、変更可能な複合型)、===チェックがアイデンティティをオブジェクトの

  • xyはメモリ内の同じ場所に格納された同一のオブジェクトである場合x === yは真です。
  • xyの型が同じで、同じ構造である場合、対応するコンポーネントがすべて再帰的に===である場合、変更可能な複合型の場合は、x === yが真となります。
  • ビットタイプ(Intまたはのような不変のチャンク)の場合、xおよびyが全く同じビットを含む場合、x === yは真です。

これらのルールは、再帰的に適用され、===の動作を定義します。一方、==関数はユーザ定義可能であり、 "抽象値の等価性"を実装します。 Overloadabilityは1つの重要な違いです:

  • ===はオーバーロードではありません - それは固定され、事前に定義された動作と組み込み関数です。その動作を拡張したり変更したりすることはできません。
  • ==はオーバーロードが可能です。通常の(Juliaの)汎用関数でインフィクス構文です。これには、ユーザー定義型の便利な既定の動作を与えるフォールバック定義がありますが、新しい型の具体的なメソッドを型に==に追加することで、それを適切に変更することができます。

==のためにどのように動作するかについてのより詳細な情報を提供するために、種類を内蔵しており、人々はthe docsから、それを拡張する際には、ユーザー定義型のためにどのように振る舞うべきか:

例えば

、すべての数値型であります数値で比較して、 タイプを無視します。文字列は、文字列として比較され、 エンコーディングは無視されます。

「直感的な平等」と考えることができます。二つの数が数値的に等しい場合、それらは==ある:

julia> 1 == 1.0 == 1 + 0im == 1.0 + 0.0im == 1//1 
true 

julia> 0.5 == 1/2 == 1//2 
true 

ただし==正確な数値平等実現すること:2/3は、その浮動小数点値0.6666666666666666あるため

julia> 2/3 == 2//3 
false 

をこれらの値が等しくありません(または有理値の場合はジュリア記法で2//3)に最も近いFloat64ですが、0.6666666666666666は2/3に正確には等しくありません。さらに、==

浮動小数点数のIEEE 754セマンティクスに従います。

これは、いくつかの可能性が予想外の特性が含まれます。

  • を明確な正および負の浮動小数点ゼロ(0.0-0.0)があります:彼らは異なる動作をし、これ===なくても、==です。
  • 多くの異なる非番号(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> a = [1, NaN, 3] 
3-element Array{Float64,1}: 
    1.0 
NaN 
    3.0 

julia> a == a 
false 

===

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 

したがって、これはスカラー==比較の弱点を継承します一方、比較は常にオブジェクトの同一性をテストするので、たとえ2つの配列が同じ型を持ち、同じ値を含んでいても、tちょっと同じ配列です:===があるabではないことを

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 

理由彼らは現在は、彼らが同じオブジェクト可変としないので、ここでは同じデータが含まれているために起こるにもかかわらず、あなたができることそのうちの一つを変異させ、その後、それは彼らが異なっていることが明らかになるだろう:

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 

したがって、あなたがabが変異によって異なるオブジェクトであることを伝えることができます。同じロジックは、不変オブジェクトには適用されません。同じデータを含む場合、同じ値を持つ限り、区別できません。したがって、不変の値は、特定の場所に結びついていることから解放されます。これは、コンパイラが不変の値の使用をそのように効果的に最適化できる理由の1つです。

関連項目:

関連する問題