我遇到使用setcdr
的行为,似乎表明它不局限于在不同缓冲区中包含相同名称的缓冲区局部变量。我尝试过使用with-current-buffer
,但这并没有解决问题。
例如,buffer-A
和buffer-B
都包含一个名为variable-one
的本地变量,它是一个cons
单元格,例如(overlay-string t)
,以及setcdr
用于将cdr
值设置为t
或nil
。
有没有办法确保setcdr
仅限于修改缓冲区本地值?
答案 0 :(得分:6)
不, 列表的cdr没有缓冲区本地值。
如果两个变量指向同一个列表,并且您修改了列表,那么您将在两个变量中看到效果。
这与缓冲区局部变量无关,而与将变量分配给变量的意义有关。
如果您希望两个变量指向不同的列表,则需要复制整个列表。
您可以使用(copy-sequence LIST)
复制列表。或者(append LIST nil)
也很常见(因为附加副本除了最终参数之外的所有副本)。
n.b。这些函数创建一个新列表结构,但列表中的值仍然是原始对象。通常情况下,所有这些都是必需的,但如果您确实需要列表内容完全相互独立,那么请改用copy-tree
。
答案 1 :(得分:3)
我认为你不能像setcdr
那样修改绑定到你声明的buffer-local变量的值。如果您没有为缓冲区局部变量分配新值,则该值是其默认值。请注意, buffer local 是变量名与其值的绑定。
唯一的方法(我知道)是将一个副本分配给缓冲区局部变量,然后使用setcdr
。
这需要在每个缓冲区中完成。
另一种方法是根本不使用setcdr
,而是使用setq
代替:
(setcdr foo bar) ===> (setq foo (cons (car foo) bar))