perché gethash non restituirà il valore della mia chiave?


8

Programmatore esperto di lisp, schema e clojure che passa a elisp da Python per automatizzare le attività di routine, quotidiane, di base: ho avuto un'enorme sorpresa da quanto segue ielm

ELISP> (setq h2 (make-hash-table))
#s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8 data ())
ELISP> (puthash "a" 1 h2)
1 (#o1, #x1, ?\C-a)
ELISP> (gethash "a" h2)
nil

eh? La chiave e il valore sembrano essere presenti:

ELISP> h2
#s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8 data ("a" 1))

/ schiaffeggia la fronte. Mi manca qualcosa di totalmente ovvio. Le informazioni dicono:

-- Function: gethash key table &optional default
 This function looks up KEY in TABLE, and returns its associated
 VALUE—or DEFAULT, if KEY has no association in TABLE.

grande. Vediamo se riusciamo gethasha restituire qualcosa di diverso da nil:

ELISP> (gethash "a" h2 'fubar) 
fubar

Wow. Ok, sono molto più stupido di quanto pensassi. Cosa diavolo sto facendo di sbagliato?

Risposte:


13

Il test di appartenenza predefinito per una tabella hash è eql. Se desideri utilizzare una stringa come chiave, impostala equalinvece su:

(setf hash (make-hash-table :test #'equal))
(puthash "a" 1 hash)
(gethash "a" hash)                      ; ==> 1

Per riferimento, ecco la parte rilevante della documentazione:

make-hash-table è una funzione integrata in "codice sorgente C".

(make-hash-table &rest KEYWORD-ARGS)

Crea e restituisce una nuova tabella hash.

Gli argomenti sono specificati come coppie di parole chiave / argomento. Sono definiti i seguenti argomenti:

:testTEST - TEST deve essere un simbolo che specifica come confrontare le chiavi. L'impostazione predefinita è eql. Predefinito sono le prove eq, eqle equal. Le funzioni di test e hash fornite dall'utente possono essere specificate tramite define-hash-table-test.


Immagino che tecnicamente non passi un simbolo come :testparametro nel tuo esempio ...
Sean,

string-equalpotrebbe avere dei vantaggi equalse so che la mia tabella hash ha stringhe solo come chiavi. Non sono sicuro del motivo per cui elisp abbia entrambi string-equale equal, poiché equalpuò essere utilizzato in qualsiasi posto che string-equalpuò essere utilizzato modulo, il fatto che string-equalgenera errori di digitazione quando non gli dai stringhe. Forse è un comportamento desiderato.
Reb.Cabin
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.