Odpowiedź, jak się okazuje, jest użycie 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"
Było dokładnie jedno pytanie udało mi się znaleźć na przepełnienie stosu, który poprosił o tym: short-cutting equality checking in F#? I od tematu to pytanie niemal sprawił, że rzucam okiem tuż obok, pomyślałem, że znowu zadam (i odpowiem) na to pytanie. Mam nadzieję, że temat tego pytania będzie łatwiej znaleźć podczas Googling dla takich terminów jak "referencyjna równość w F #".
Co z numerem obj.ReferenceEquals
?
W komentarzu Fyodor Soikin pyta, co jest nie tak z obj.ReferenceEquals
. Odpowiedź brzmi „nie bardzo”, ale istnieją dwa sposoby, w których LanguagePrimitives.PhysicalEquality
jest lepsza niż obj.ReferenceEquals
dla większości F # Kod:
1) PhysicalEquality
generuje błąd kompilatora kiedy przechodzą dwa różne typy, natomiast obj.ReferenceEquals
zajmuje tylko dwa obj
s, a więc szczęśliwie próbuje porównać int list
do char 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
nie pozwoli Ci porównać typy wartości, tylko typy referencyjne. obj.ReferenceEquals
pozwoli ci porównać dwa typy wartości i domyślnie je najpierw zapełni. Ale to pudełka każda oddzielnie, co oznacza, że będzie zawsze return false nawet jeśli dał mu „ten sam” obiekt o wartości:
let n = 3
let n' = n
obj.ReferenceEquals(n,n') // Returns false!
LanguagePrimitives.PhysicalEquality n n' // Compiler error
i, oczywiście, jest jeszcze jedna różnica, która sprowadza się do osobistych preferencje i łatwość użycia. PhysicalEquality
ma parametry w stylu curry, które ładnie grają z wnioskiem o typ i aplikacją częściową. obj.ReferenceEquals
przyjmuje parametry w stylu krotki, co oznacza, że jest nieco brzydszy w użyciu.
Z tych wszystkich powodów, LanguagePrimitives.PhysicalEquality
lepiej jest użyć w prawie każdy scenariusz, niż obj.ReferenceEquals
.
Coś nie tak z dobrym starym 'obj.ReferenceEquals'? –
@FyodorSoikin - Napisałem dwa komentarze w odpowiedzi na twoje pytanie, a następnie zdałem sobie sprawę, że będą lepsze w odpowiedzi, z przykładami kodu. Więc proszę: 'obj.ReferenceEquals' nie jest ** zły **, ale' PhysicalEquality' jest lepszy, ponieważ daje błędy typu, jeśli spróbujesz porównać dwa różne typy. (Co jest prawie na pewno błędem w twoim kodzie, a ty * chcesz * kompilatorem, aby pomóc ci go złapać). – rmunn