gpt4 book ai didi

lisp - 为什么这个全局变量只能设置两次,不能再设置了?

转载 作者:太空宇宙 更新时间:2023-11-03 18:50:55 24 4
gpt4 key购买 nike

我试图在 elisp 中制作一个简单的解析器,但我遇到了一个问题,我将 defvar 设置为全局变量,然后我将 setq 一个新值放入其中。这是第一次。然而,后来 setq 每次都失败。

下面的代码是问题的简化:

(defvar buf '(BUF))
(defvar head nil)

(defun pparse (seq)

(defun status ()
(princ (format "Parse: %40s || %-20s\n"
(prin1-to-string seq) (prin1-to-string buf))))

(while seq
(status)
(setq head (car seq))
(setq seq (cdr seq))
(cond ((equal "x" head)
(nconc buf (list head)))
((equal "," head)
(setq buf '(BUF))
;;(setcdr buf nil) <- fixes it but doesn't answer my question
)))

(status))

(pparse '("x" "," "x" "," "x" "," "x"))

产生这个输出:

Parse:            ("x" "," "x" "," "x" "," "x") || (BUF)               
Parse: ("," "x" "," "x" "," "x") || (BUF "x")
Parse: ("x" "," "x" "," "x") || (BUF)
Parse: ("," "x" "," "x") || (BUF "x")
Parse: ("x" "," "x") || (BUF "x")
Parse: ("," "x") || (BUF "x" "x")
Parse: ("x") || (BUF "x" "x")
Parse: nil || (BUF "x" "x" "x")

如您所见,第二列被剪裁了一次,但随后每次都增长。

如果您取消注释 setcdr 行,这将按预期工作(输出如下)。您甚至可以转储 setq。我理解为什么这会修复它,但不理解为什么最初会发生原始错误。

Parse:            ("x" "," "x" "," "x" "," "x") || (BUF)               
Parse: ("," "x" "," "x" "," "x") || (BUF "x")
Parse: ("x" "," "x" "," "x") || (BUF)
Parse: ("," "x" "," "x") || (BUF "x")
Parse: ("x" "," "x") || (BUF)
Parse: ("," "x") || (BUF "x")
Parse: ("x") || (BUF)
Parse: nil || (BUF "x")

顺便说一句,即使我关闭词法范围,行为也是一样的。

最佳答案

您不能改变文字数据,例如 '(BUF),并期望得到合理的结果。在您的代码中,nconc 是一个变异操作。

就您所看到的行为的“原因”而言,这是由于 (setq buf '(BUF)) 表达式造成的。这每次都将它设置为相同 对象,因为它是一个文字数据——您不应该用 nconc 之类的东西来改变它。如果您将其更改为 (setq buf (list 'BUF)),那么它每次都会生成一个新对象,您可以安全地nconc that.

关于lisp - 为什么这个全局变量只能设置两次,不能再设置了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37777474/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com