Cela semble être une comparaison d'équivalence pour certains types, mais pas pour les chaînes.
# 3 != 3;;
- : bool = false
# 3 != 2;;
- : bool = true
C'est comme prévu.
# "odp" = "odp";;
- : bool = true
# "odp" != "odp";;
- : bool = true
# "odp" <> "odp";;
- : bool = false
Pourquoi "odp" != "odp"
évaluer en true
? Que fait-il réellement? Cela ne devrait-il pas générer une erreur de type?
vous avez fait la différence entre l'égalité structurelle et l'égalité physique.
<>
est à =
(égalité structurelle) comme !=
est à ==
(égalité physique)
"odg" = "odg" (* true *)
"odg" == "odg" (* false *)
est faux car chacun est instancié dans différents emplacements de mémoire, en faisant:
let v = "odg"
v == v (* true *)
v = v (* true *)
La plupart du temps, vous voudrez utiliser =
et <>
.
modifier quand l'égalité structurelle et physique sont équivalentes :
Vous pouvez utiliser la fonction what_is_it et découvrir tous les types qui seraient égaux à la fois structurellement et physiquement. Comme mentionné dans les commentaires ci-dessous, et dans l'article lié, les caractères, les entiers, l'unité, la liste vide et certaines instances de types de variantes auront cette propriété.
Le contraire pour !=
L'opérateur est ==
, pas l'opérateur =
une.
# "a" != "a" ;;
- : bool = true
# "a" == "a" ;;
- : bool = false
L'opérateur == est une "égalité physique". Lorsque vous tapez "a" == "a"
, vous comparez deux instances différentes de chaînes qui se ressemblent, donc l'opérateur retourne false
. Tout en ayant une instance, cela retourne vrai:
# let str = "a"
in str == str ;;
- : bool = true
# let str = "a"
in str != str ;;
- : bool = false
Une explication rapide sur ==
Et !=
Dans OCaml en plus de toutes les bonnes réponses qui ont déjà été fournies:
1/==
Et !=
Exposent des détails d'implémentation que vous ne voulez vraiment pas connaître. Exemple:
# 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
Jusqu'à présent, tout va bien: x
et t.(0)
sont physiquement égaux car t.(0)
contient un pointeur vers le même bloc que x
pointe. C'est ce que dicte la connaissance de base de l'implémentation. MAIS:
# 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
Ce que vous voyez ici sont les résultats d'une optimisation autrement utile impliquant des flottants.
2/D'un autre côté, il existe un moyen sûr d'utiliser ==
, Et c'est un moyen rapide mais incomplet de vérifier l'égalité structurelle.
Si vous écrivez une fonction d'égalité sur des arbres binaires
let equal t1 t2 =
match ...
vérifier t1
et t2
pour une égalité physique est un moyen rapide de détecter qu'ils sont évidemment structurellement égaux, sans même avoir à les consulter et à les lire. C'est:
let equal t1 t2 =
if t1 == t2
then true
else
match ...
Et si vous gardez à l'esprit que dans OCaml, l'opérateur "booléen ou" est "paresseux",
let equal t1 t1 =
(t1 == t2) ||
match ...
Ils sont comme deux "Tom" dans ta classe! Car:
Dans ce cas, "odp" = "odp"
car ce sont DEUX chaînes avec MÊME VALEUR !!
Ils ne sont donc pas ==
car ils sont DEUX chaînes différentes stockées dans différent (mémoire) emplacement
Elles sont =
car ils ont la valeur de chaîne identique.
Un peu plus loin, "odp" est une variable anonyme. Et deux variables anonymes mènent à cela Deux chaînes.
Pour ta convenance:
# "odp" = "odp";;
- : bool = true
# "odp" != "odp";;
- : bool = true
# "odp" <> "odp";;
- : bool = false
les entiers sont le seul type où l'égalité physique et structurelle sont identiques, car les entiers sont le seul type qui n'est pas en boîte