Помимо переходящих политик и др. (где один размер определенно не соответствует всем), у Вас должны быть хорошие фиксации:
you have experienced the difference between structural and physical equality.
<>
is to =
(structural equality) as !=
is to ==
(physical equality)
"odg" = "odg" (* true *)
"odg" == "odg" (* false *)
is false because each is instantiated in different memory locations, doing:
let v = "odg"
v == v (* true *)
v = v (* true *)
Most of the time you'll want to use =
and <>
.
edit about when structural and physical equality are equivalent:
You can use the what_is_it function and find out all the types that would be equal both structurally and physically. As mentioned in the comments below, and in the linked article, characters, integers, unit, empty list, and some instances of variant types will have this property.
The opposite for !=
operator is ==
operator, not the =
one.
# "a" != "a" ;;
- : bool = true
# "a" == "a" ;;
- : bool = false
The == operator is a "physical equality". When you type "a" == "a"
, you compare two different instances of strings that happen to look alike, so the operator returns false
. While having one instance makes it return true:
# let str = "a"
in str == str ;;
- : bool = true
# let str = "a"
in str != str ;;
- : bool = false
Краткое описание ==
и ! =
в OCaml в дополнение ко всем уже предоставленным правильным ответам:
1 / ==
и ! =
раскрывают детали реализации, о которых вы действительно не хотите знать. Пример:
# let x = Some [] ;;
val x : 'a list option = Some []
# let t = Array.create 1 x ;;
val t : '_a list option array = [|Some []|]
# x == t.(0) ;;
- : bool = true
Пока все хорошо: x
и t. (0)
физически равны, потому что t. (0)
содержит указатель на тот же блок, на который указывает x
. Это то, что диктует базовые знания о реализации. НО:
# let x = 1.125 ;;
val x : float = 1.125
# let t = Array.create 1 x ;;
val t : float array = [|1.125|]
# x == t.(0) ;;
- : bool = false
То, что вы видите здесь, - это результаты полезной оптимизации с использованием чисел с плавающей запятой.
2 / С другой стороны, есть безопасный способ использования ==
, а именно как быстрый, но неполный способ проверить структурное равенство.
Если вы пишете функцию равенства для двоичных деревьев
let equal t1 t2 =
match ...
, проверка t1
и t2
на физическое равенство - это быстрый способ определить, что они явно структурно равны, даже без приходиться повторять и читать их. То есть:
let equal t1 t2 =
if t1 == t2
then true
else
match ...
И если вы помните, что в OCaml оператор «логическое или» является «ленивым»,
let equal t1 t1 =
(t1 == t2) ||
match ...
ints are the only type where physical and structural equality are the same, because ints are the only type that is unboxed