关于car和cdr的Wikipedia页面说a cons是一对指针.
以下代码似乎证实:
(progn
(setq a '(1 . 2))
(setq b a)
(setf (car b) 10)
(print a))
Run Code Online (Sandbox Code Playgroud)
对该形式的评估给出了缺点(10 . 2).设置car的b变化car的a.您可以在compileonline.com上的在线代表中尝试.
Common Lisp规范中定义的行为在哪里?
(我已经阅读了一些文字,但找不到针对该行为的部分.)
有趣的是,维基百科上的conses页面说" cons构造存储两个值或指向值的内存对象".如果原子1直接存储在cons对象中,那么改变b不会改变a,是吗?
我在上面假设a并b保持cons对象而不是指向conses的指针.即使实际的lisp实现与指针一起使用,这在repl级别上也不应该是可见的,还是应该根据规范?当人们假设a并b保持指向两者的指针时,可以实现类似的效果cons.
Consing,即通过重复应用来构建列表cons,支持假设conses由符号值中的指针表示.
以下两种形式是等效的:
(let ((a '(1)))
(setq b (cons 2 a)))
Run Code Online (Sandbox Code Playgroud)
(setq b '(2 1))
Run Code Online (Sandbox Code Playgroud)
设置b的车改变了汽车.
你是不是设置car的b.您正在设置car由b和引用的相同cons单元格a.
CL-USER 1 > (let (a b)
(setq a (cons 1 2))
(setq b a)
(eq a b))
T
Run Code Online (Sandbox Code Playgroud)
说明:
a和b.(cons 1 2) 返回一个cons小区(setq a (cons 1 2))设置一个(cons 1 2)cons单元格的结果.(setq b a)计算a,返回上面的cons单元格并设置b为cons单元格.要理解的关键是变量和函数的评估将非原始(不是原始数字,字符,...)对象作为自身返回 - 而不是作为副本.
我假设a和b持有cons对象而不是指向conses的指针.
那是错的.a并且b是变量,它们只指向同一个单一的cons单元格.
"cons构造了包含两个值或指向值的指针的内存对象"
在Common Lisp实现中,类似小数字(fixnums)的东西可能直接存储在cons单元格中.一个不能可靠地通过身份(使用比较数字EQ),并有做数值比较(EQL,=,...).
OTOH,cons细胞不能存储在cons细胞内,因此在内部由指针引用.
您使用的操作:
SETQ:评估第一个form1,结果存储在变量var1中.- >注意它是怎么说的:结果而不是结果的副本.
RPLCA - 这是(setf CAR)实际使用的.:rplaca用对象替换cons的汽车并且cons被修改 - >因此它修改了作为参数传递的cons对象.
评估 - 自执行代码以来,评估规则适用.
进一步了解Lisp的执行模型: