答えは、結局のところ、LanguagePrimitives.PhysicalEquality
を使用することです:
let isSameObject = LanguagePrimitives.PhysicalEquality
let a = [1; 2; 3]
let b = [1; 2; 3]
let a' = a
printfn "%A" (isSameObject a b) // Prints "false"
printfn "%A" (isSameObject a a') // Prints "true"
私はこのことについて尋ねたスタックオーバーフロー上で見つけることができ、正確に一つの質問がありました: short-cutting equality checking in F#?そして、その質問の対象からはほとんどそれを過ぎて私に一目惚れさせました、私は質問をもう一度尋ねる(そして答える)と思った。うまくいけば、この質問の件名は、「F#での参照平等」のような用語のためにグーグルで見つけやすくなります。
obj.ReferenceEquals
について
コメントで、Fyodor Soikinは何が間違っているのかをobj.ReferenceEquals
に尋ねます。答えは、「あまりない」が、LanguagePrimitives.PhysicalEquality
は、ほとんどのF#コードについてobj.ReferenceEquals
よりも優れている2つの方法があります。
1)は、あなたがそれを二つの異なるタイプを渡すときobj.ReferenceEquals
はちょうど2つのobj
をとりながらPhysicalEquality
は、コンパイラエラーがスローされますしたがって、Sと喜んchar list
にint list
を比較しようとします:
let a = [1;2;3]
let b = ['a';'b';'c']
obj.ReferenceEquals(a,b) // Returns false
LanguagePrimitives.PhysicalEquality a b // Compiler error
2)PhysicalEquality
は、あなたが値型を比較するだけで参照タイプをさせません。 obj.ReferenceEquals
は、2つの値の型を比較させ、最初に暗黙的にボックスに入れます。
let n = 3
let n' = n
obj.ReferenceEquals(n,n') // Returns false!
LanguagePrimitives.PhysicalEquality n n' // Compiler error
そして、もちろん、個人的に沸く一つの他の違いが、あります:それは常にあなたがそれを「同じ」値オブジェクトを与えた場合でも、falseを返しれることを意味しかし、ボックス別途各1、使いやすさと使いやすさを提供します。 PhysicalEquality
はカレースタイルのパラメータを取ります。これは型推論と部分的なアプリケーションでうまくいきます。 obj.ReferenceEquals
は、タプルスタイルのパラメータを取ります。これは、使用するにはやや醜いことを意味します。
これらの理由から、obj.ReferenceEquals
よりものほうが、がよく、それぞれになります。
良い古い 'obj.ReferenceEquals'には何も間違っていますか? –
@FyodorSoikin - 私はあなたの質問に答えて2つのコメントを書いた後、答えの中でコード例を使ってよりうまくいくことに気付きました。そこで、あなたは行く: 'obj.ReferenceEquals'は**悪い**ではありませんが、2つの異なる型を比較しようとすると型のエラーが出るので、' PhysicalEquality'が優れています。 (これはほぼ確実にあなたのコードのバグであり、あなたが*それをキャッチするためにコンパイラを望んでいる)。 – rmunn