Chi*_*ron 13 lisp common-lisp land-of-lisp
我正在阅读"Lisp的土地"(顺便说一下,这是我读过的最好的技术书籍之一)我遇到了关联列表
(defparameter *edges*
'((living-room (garden west door)
(attic upstairs ladder))
(garden (living-room east door))
(attic (living-room downstairs ladder))))
Run Code Online (Sandbox Code Playgroud)
首先,Lisp中的关联列表与Java的Map(键值绑定)相同吗?
对于客厅钥匙,如何拥有多个价值?为什么不用列表包含值:
(living-room ((garden west door) (attic upstairs ladder)))
Run Code Online (Sandbox Code Playgroud)
Nie*_*jou 13
是的,关联列表是表达键值关联的一种方式.Common Lisp为此提供的其他结构是属性列表和哈希表.
该值实际上已包含在列表中.alist基本上是对的列表,其中每对的汽车是钥匙,而cdr是与该钥匙相关联的值.如果您使用ASSOC查找关键LIVING-ROOM并将CDR应用于结果:
CL-USER> (cdr (assoc 'living-room *edges*)) ((GARDEN WEST DOOR) (ATTIC UPSTAIRS LADDER))
这背后的魔力在于这样一个事实:由于列表是由成对构造的,因此一对汽车是living-room并且其cdr是两个元素的列表(garden west door)并且(attic upstairs ladder)也可以被视为三元素列表(living-room (garden west door) (attic upstairs ladder)).
通常,当将alists表示为带引号的对象时,您会看到用虚线对明确描述的元素,而不是使用列表表示法,例如:
(defparameter *edges*
'((living-room . ((garden west door)
(attic upstairs ladder)))
(garden . ((living-room east door)))
(attic . ((living-room downstairs ladder))) ))
ASSOC返回cons单元,因此包括键和值.
原因是这使得破坏性地更新值(或密钥)变得容易.
这里的更新隐藏在SETF后面:
CL-USER 11 > (defparameter *edges*
(copy-tree
'((living-room (garden west door)
(attic upstairs ladder))
(garden (living-room east door))
(attic (living-room downstairs ladder)))))
*EDGES*
CL-USER 12 > (assoc 'living-room *edges*)
(LIVING-ROOM (GARDEN WEST DOOR) (ATTIC UPSTAIRS LADDER))
CL-USER 13 > (cdr (assoc 'living-room *edges*))
((GARDEN WEST DOOR) (ATTIC UPSTAIRS LADDER))
CL-USER 14 > (setf (cdr (assoc 'living-room *edges*)) '((garden east door)))
((GARDEN EAST DOOR))
CL-USER 15 > (cdr (assoc 'living-room *edges*))
((GARDEN EAST DOOR))
Run Code Online (Sandbox Code Playgroud)