Domanda
Sembra essere un confronto di equivalenza per alcuni tipi, ma non per le stringhe.
# 3 != 3;;
- : bool = false
# 3 != 2;;
- : bool = true
Questo è come previsto.
# "odp" = "odp";;
- : bool = true
# "odp" != "odp";;
- : bool = true
# "odp" <> "odp";;
- : bool = false
Perché "odp" != "odp"
valuta true
? Che cosa sta realmente facendo? Non dovrebbe generare un errore di tipo?
Soluzione
hai sperimentato la differenza tra l'uguaglianza strutturale e fisica.
<>
è =
(uguaglianza strutturale) come !=
è ==
(uguaglianza fisica)
"odg" = "odg" (* true *)
"odg" == "odg" (* false *)
è falso perché ognuno è istanziato in diverse posizioni di memoria, facendo:
let v = "odg"
v == v (* true *)
v = v (* true *)
La maggior parte delle volte ti consigliamo di utilizzare <=> e <=>.
modifica di quando l'uguaglianza strutturale e fisica sono equivalenti :
Puoi utilizzare la what_is_it function e scoprire tutti i tipi che sarebbero uguali sia strutturalmente che fisicamente. Come menzionato nei commenti seguenti e nell'articolo collegato, caratteri, numeri interi, unità, elenco vuoto e alcune istanze di tipi di variante avranno questa proprietà.
Altri suggerimenti
Il contrario di !=
operatore è ==
operatore, non =
.
# "a" != "a" ;;
- : bool = true
# "a" == "a" ;;
- : bool = false
L'operatore == è un " uguaglianza fisica " ;. Quando si digita "a" == "a"
, si confrontano due diverse istanze di stringhe che sembrano simili, quindi l'operatore restituisce false
. Pur avendo un'istanza, lo restituisce true:
# let str = "a"
in str == str ;;
- : bool = true
# let str = "a"
in str != str ;;
- : bool = false
Una breve spiegazione di ==
e !=
in OCaml oltre a tutte le risposte corrette che sono già state fornite:
1 / x
e t.(0)
espongono dettagli di implementazione che non vuoi davvero conoscere. Esempio:
# 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
Fin qui tutto bene: t1
e t2
sono fisicamente uguali perché <=> contiene un puntatore allo stesso blocco a cui <=> punta. Questo è ciò che impone la conoscenza di base dell'implementazione. MA:
# 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
Quello che vedi qui sono i risultati di un'ottimizzazione altrimenti utile che coinvolge i float.
2 / D'altra parte, c'è un modo sicuro per usare <=>, ed è un modo rapido ma incompleto per verificare l'uguaglianza strutturale.
Se stai scrivendo una funzione di uguaglianza su alberi binari
let equal t1 t2 =
match ...
il controllo di <=> e <=> per l'uguaglianza fisica è un modo rapido per rilevare che sono ovviamente strutturalmente uguali, senza nemmeno dover ricorrere e leggerli. Cioè:
let equal t1 t2 =
if t1 == t2
then true
else
match ...
E se tieni presente che in OCaml il & # 8220; booleano o & # 8221; l'operatore è & # 8220; pigro & # 8221 ;,
let equal t1 t1 =
(t1 == t2) ||
match ...
Sono come due " Tom " s nella tua classe! Perché:
In questo caso, "odp" = "odp"
perché sono DUE stringhe con STESSO VALORE !!
Quindi non sono ==
perché sono DUE diverse stringhe archiviate in diverse (Memoria) posizione
Sono =
perché hanno il valore stringa identico .
Un altro passo più in profondità, " odp " è una variabile anonima. E due variabili anonime portano a queste Due stringhe.
Per comodità:
# "odp" = "odp";;
- : bool = true
# "odp" != "odp";;
- : bool = true
# "odp" <> "odp";;
- : bool = false
gli ints sono l'unico tipo in cui l'uguaglianza fisica e strutturale sono uguali, perché gli ints sono l'unico tipo che non è in box