gethashがキーの値を返さないのはなぜですか?


8

ルーチン、日常、基本タスクを自動化するためにpythonからelispに移行する経験豊富なlisp、scheme、clojureプログラマー:次のことから私は非常に驚きました 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

え?キーと値が存在するように見えます:

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

/額を平手打ち。私は完全に明白な何かを見逃しているに違いありません。情報は言う:

-- 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.

すごい。gethash以外のものを返すことができるかどうか見てみましょうnil

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

ワオ。わかりました、思ったよりもずっと気難しいです。いったい何が悪いのでしょうか?

回答:


13

ハッシュテーブルのデフォルトのメンバーシップテストはeqlです。文字列をキーとして使用する場合は、equal代わりに次のように設定します。

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

参考までに、docstringの関連部分を次に示します。

make-hash-table `Cソースコード 'の組み込み関数です。

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

新しいハッシュテーブルを作成して返します。

引数は、キーワード/引数のペアとして指定されます。次の引数が定義されています。

:testTEST-TESTは、キーの比較方法を指定する記号でなければなりません。デフォルトはeqlです。事前に定義され、テストされているeqeqlequal。ユーザー提供のテストおよびハッシュ関数はを介して指定できます define-hash-table-test


技術的には:test、例のパラメータとしてシンボルを渡していないと思います...
Sean

string-equalequalハッシュテーブルにキーとしてのみ文字列があることがわかっている場合は、いくつかの利点があるかもしれません。elispのは両方を持っている私はなぜわからないstring-equalequalので、equal任意の場所で使用することができstring-equal剰余実際に使用することができstring-equalますが、それを文字列を与えていない時に型エラーをスローします。多分それは望ましい行動です。
Reb.Cabin 2015年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.