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?

È stato utile?

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top