【问题标题】:How to use `setcdr` with buffer-local variables如何将`setcdr`与缓冲区局部变量一起使用
【发布时间】:2014-08-26 07:41:59
【问题描述】:

我在使用setcdr 时遇到了一些行为,这似乎表明它不仅限于在不同缓冲区中包含相同名称的缓冲区局部变量。我尝试过使用with-current-buffer,但这并不能解决问题。

例如,buffer-Abuffer-B 都包含一个名为 variable-one 的局部变量,这是一个 cons 单元格 - 例如,(overlay-string t),而 setcdr 用于设置 @ 987654329@ 的值为 tnil

有没有办法确保setcdr 仍然仅限于修改缓冲区本地值?

【问题讨论】:

  • 谢谢你们,@phils 和 @ale -- 我在这个线程中学习的课程的使用需要至少一杯咖啡,因为我是使用dolist 宏和列表/变量是几个(car (car (cdr (car (cdr . . . 深。明天早上我会再把它捡起来。非常感谢您的回答!!!

标签: emacs elisp


【解决方案1】:

不,列表的 cdr 没有缓冲区本地值。

如果两个变量指向同一个列表,并且您修改了该列表,那么您将在两个变量中看到效果。

这与缓冲区局部变量无关,而是与将列表分配给变量的含义有关。

如果你想让这两个变量指向不同的列表,那么你需要复制整个列表。

您可以使用(copy-sequence LIST) 复制列表。或者(append LIST nil) 也很常见(作为追加副本,除了最后一个参数)。

n.b.这些函数创建了一个新列表结构,但列表中的仍然是原始对象。通常这就是所有需要的,但如果您确实需要列表内容完全相互独立,那么请改用copy-tree

【讨论】:

    【解决方案2】:

    我认为你不能,就像setcdr 一样,你正在修改绑定到你声明的缓冲区本地变量的值。如果您没有为缓冲区局部变量分配新值,则该值是其默认值。请注意,本地缓冲区是变量名与其值的绑定。

    唯一的方法(据我所知)是将一个副本分配给您的缓冲区局部变量,然后使用setcdr。 这需要在每个缓冲区中完成。

    另一种方法是根本不使用setcdr,而是使用setq

    (setcdr foo bar) ===> (setq foo (cons (car foo) bar))

    【讨论】:

    • 你的答案是正确的,上面的答案也是正确的,但我只能选择一个。我最终将您的建议与上面的copy-sequence 建议结合使用。非常感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多