String 如何在Lisp中生成局部字符串变量?

String 如何在Lisp中生成局部字符串变量?,string,lisp,common-lisp,String,Lisp,Common Lisp,我试图创建一个局部字符串变量,并使用变量构建字符串 (setq string-label (make-array 0 :element-type `character :fill-pointer 0 :adjustable t)) (loop while (and (char/= char #\Space) (char/= char

我试图创建一个局部字符串变量,并使用变量构建字符串

(setq string-label (make-array 0 :element-type `character
                                 :fill-pointer 0
                                 :adjustable t))
(loop while (and (char/= char #\Space)
                 (char/= char #\()
                 (char/= char #\Newline))
      do
         (vector-push-extend char string-label)
         (setq char (read-char fstream nil)))
我得到一个错误:

*** - SETQ: variable STRING_LABEL has no value

我假设您运行的代码与您给出的代码不同,因为该代码中没有对
string\u label
的引用

然而,您所展示的代码中还有足够多的其他问题值得修复。这些基本上是

  • 您不应该通过赋值来绑定变量,更不用说局部变量了,事实上,这样做在CL中是不合法的–相反,您应该使用像
    let
    (在下面的代码中,我使用
    loop
    来为我做绑定)
  • 在绑定之前,您使用的是
    char
    (即使这样,它实际上也没有绑定,因为您只是使用
    setq
  • 读取标签的终止条件不正确–如果您点击EOF,您将得到一个错误,因为
    char
    将是
    nil
此外,代码中还存在一些不规则之处:当您遇到一个“stopper”字符时,是否希望将其作为下一个要读取的字符?我的版本假设你会。当然,这对函数的连续调用有影响:您需要向前跳过stopper

因此,这里是代码的一个清理版本,作为函数呈现。这也使得“stopper”字符列表成为函数的参数,并使用
member
来知道何时停止(
member
默认使用
eql
,并且
eql
与字符上的
char=
相同,因此这很好)


定义局部变量的主要结构是
let
let*
。从
let
派生的其他运算符也绑定局部变量,例如使用打开的文件
解构绑定
。当然,
lambda
和由此派生的函数定义形式,如
defun
都有参数,这些都是局部变量。(历史上,
lambda
存在于
let
之前)

循环
构造中,可以使用
with
子句定义局部变量,如下所示:

;; Like a hidden (let ((x 42) ...) in the code generated by loop:

(loop with x = 42 ...)
这允许许多
循环的实例
避免被额外的
let
包围,从而看起来更“整洁”

局部变量也可以在
循环
的迭代中自动步进,如果逻辑正确,在许多情况下可以避免合并笨重的
setq
赋值形式:

;; x is initially 1, then 2, 3, ...

(loop with x = 1 then (+ 1 x) ...)
通用Lisp中的全局变量是使用
defvar
defparameter
定义的,而不是简单地用
setf
setq
赋值

对以前未定义的变量简单地发出
setf
setq
的效果会受到ANSI Lisp的“灰色区域”的影响,并且由于灰色区域的不同解释,在不同的实现中表现不同


在某些实现中,未定义变量上的
setq
会产生诊断。在其他情况下,它会创建一个特殊变量,类似于
defparameter
,在其他情况下,它会创建类似于“全局词法”变量的东西:符号接收绑定,但没有标记为特殊变量,仍然可用于词法绑定。

STRING\u标签有下划线。这是从哪里来的?请参见
makestring
。示例:
(生成字符串8:初始元素#\o)
。还有
make string
fill
。string\u标签是一个打字错误。它应该是字符串标签。非常感谢。
;; x is initially 1, then 2, 3, ...

(loop with x = 1 then (+ 1 x) ...)