我正在尋找一種可能非冗長的可移植方式來初始化Common Lisp中的一個散列表。例如。一些適用於常量散列表的工作,也用於預加載可變散列。在CLISP我使用:Common Lisp:用很多條目初始化一個散列表的速記
(defconstant +my-map+ #S(HASH-TABLE :TEST FASTHASH-EQ
(key1 . "value1")
...
(keyN . "valueN")
))
但不幸的是,這種格式只適用於CLISP。
我正在尋找一種可能非冗長的可移植方式來初始化Common Lisp中的一個散列表。例如。一些適用於常量散列表的工作,也用於預加載可變散列。在CLISP我使用:Common Lisp:用很多條目初始化一個散列表的速記
(defconstant +my-map+ #S(HASH-TABLE :TEST FASTHASH-EQ
(key1 . "value1")
...
(keyN . "valueN")
))
但不幸的是,這種格式只適用於CLISP。
人們可以在讀出時間編程構造哈希表:
(defvar *ht* #.(let ((ht (make-hash-table)))
(loop for (key . value) in
'((a . 1) (b . 2) (c . 3))
do (setf (gethash key ht) value))
ht))
(describe *ht*)
#.
用於讀出時間的評價。然後編譯器將散列表轉儲到FASL文件。
這可以被編譯:
使用SBCL:
* (compile-file "/tmp/test.lisp")
; compiling file "/private/tmp/test.lisp" (written 24 MAY 2012 10:08:49 PM):
; compiling (DEFVAR *HT* ...)
; compiling (DESCRIBE *HT*)
; /tmp/test.fasl written
; compilation finished in 0:00:00.360
#P"/private/tmp/test.fasl"
NIL
NIL
* (load *)
#<HASH-TABLE :TEST EQL :COUNT 3 {100299EA43}>
[hash-table]
Occupancy: 0.2
Rehash-threshold: 1.0
Rehash-size: 1.5
Size: 16
Synchronized: no
T
* *ht*
#<HASH-TABLE :TEST EQL :COUNT 3 {100299EA43}>
創建一個哈希表的功能:
(defun create-hashtable (alist
&key (test 'eql)
&aux (ht (make-hash-table :test test)))
(loop for (key . value) in alist
do (setf (gethash key ht) value))
ht)
非常感謝Reiner!唯一的缺點是它有點冗長,但是這可以幫助使用宏。我是一個Lisp初學者,不擅長宏。無論如何,這是我的:'(defmacro ini-hash-table(pairs) '(let((hash(make-hash-table:test'equal))) cddr do(setf(gethash key hash)value))hash))'Then then I do:'(defvar * ht *#。(ini-hash-table'(a 1 b 2 c 3)))' –
@AntonioBonifati :當我懷疑寫一個函數,而不是一個宏。沒有理由它應該是宏觀的,是嗎? –
是的,謝謝,我知道,一個很好的原因是宏很難編寫和調試。但是如果我在這種情況下寫一個函數,我不能用#來調用它。至少在ECL中它告訴我它是未定義的。我認爲這是#的效果。即任何用戶定義的函數在讀取時都不可用。我想知道是否可以編寫一個宏包裝器,允許在添加:initial-contents關鍵字參數的同時完全配置make-hash-table。這將「添加此功能的標準」:) –
Alexandria具有alist-hash-table
函數,您可能會發現它有用。
https://github.com/vseloved/rutils/ blob/master/core/readtable.lisp#L10 –
請注意,例如http://www.aiai.ed.ac.uk/~jeff/lisp/cl-pitfalls警告不要使用散列表作爲「defconstant」形式的值。 – Hugh
感謝所有。看起來這個基本特徵缺乏標準,必須以某種方式添加。除了引入新的語法,模仿Perl或PHP之外,您怎麼看待編寫一個包含make-hash-table的宏,並添加了以下選項:initial-contents,這是標準中所支持的相同選項,例如make-array?我認爲這不會很有效率,因爲內容將由必須遍歷的alist指定,但它至少與Lisp語法更一致。 –