Pointers 公共Lisp中的指针
我想保存一个引用(指针),指向保存在另一个变量中的部分数据:Pointers 公共Lisp中的指针,pointers,lisp,common-lisp,Pointers,Lisp,Common Lisp,我想保存一个引用(指针),指向保存在另一个变量中的部分数据: (let ((a (list 1 2 3))) (let ((b (car (cdr a)))) ;here I want to set b to 2, but it is set to a copy of 2 (setf b 4)) a) ;evaluates to (1 2 3) instead of (1 4 2) 我可以使用宏,但是如果要在列表中间更改一些数据,那么我将执行很多代码,而且我不是很灵活: (de
(let ((a (list 1 2 3)))
(let ((b (car (cdr a)))) ;here I want to set b to 2, but it is set to a copy of 2
(setf b 4))
a) ;evaluates to (1 2 3) instead of (1 4 2)
我可以使用宏,但是如果要在列表中间更改一些数据,那么我将执行很多代码,而且我不是很灵活:
(defparameter *list* (create-some-list-of-arrays))
(macrolet ((a () '(nth 1000 *list*)))
(macrolet ((b () `(aref 100 ,(a))))
;; I would like to change the macro a here if it were possible
;; but then b would mean something different
(setf (b) "Hello")))
是否可以创建一个变量作为引用而不是副本?如果您只需要一些语法上的修饰,请尝试: 注意,这完全是编译时的事情。任何地方(在
符号macrolet
的范围内,b
用作变量时,它在编译时被扩展为(car(cdr a))
。正如Sylvester已经指出的,CommonLisp中没有“引用”
不过,我不建议一般使用这种做法
顺便说一下:永远不要更改引用的数据。在常量列表文字上使用(setf(car…)
(及类似)如”(1 2 3)
,将产生未定义的后果
cl-user> (let ((a '(1 2 3)))
(let ((b (car (cdr a))))
(setf b 4))
a)
;Compiler warnings :
; In an anonymous lambda form: Unused lexical variable B
(1 2 3)
cons
单元格是一对指针car
取消对第一个的引用,cdr
取消对第二个的引用。你的名单是有效的
a -> [ | ] -> [ | ] -> [ | ] -> NIL
| | |
1 2 3
在定义b
的顶部,(cdr a)
将获得第二个箭头。取下该单元格的car
,将取消对第二个单元格的第一个指针的引用,并将其值传递给您。在本例中,2
。如果要更改该指针的值,需要setf
it而不是它的值
cl-user> (let ((a '(1 2 3)))
(let ((b (cdr a)))
(setf (car b) 4))
a)
(1 4 3)
基于巴格斯的建议。这并不完全是您想要的,但您可以定义setf扩展器来创建“访问器”。因此,假设您的列表包含有关处于for of(姓氏)状态的人的信息,当某人结婚时,您可以将其更新为:
(defun marital-status (person)
(third person))
(defun (setf marital-status) (value person)
(setf (third person) value))
(let ((person (list "John" "Doe" "Single")))
(setf (marital-status person) "Married")
person)
;; => ("John" "Doe" "Married")
(let((a(list 1 2 3))(setf(second a)4)a有什么问题?我强烈建议阅读本文,重点关注值、变量和位置的细节。如果您不是该语言的新手,很抱歉,但是如果您是,请记住,其他语言的映射技术不一定能为您提供好的或快速的代码。您可能会对讨论C指针、通过结构间接寻址(包括cons单元格)、通用引用、,以及模拟C风格的指针。问题并不完全相同,但我认为答案可能是您所需要的。使用引号定义的列表是常量,修改常量的效果未定义。如果要修改列表,请使用列表创建它
(defun marital-status (person)
(third person))
(defun (setf marital-status) (value person)
(setf (third person) value))
(let ((person (list "John" "Doe" "Single")))
(setf (marital-status person) "Married")
person)
;; => ("John" "Doe" "Married")