Common Lisp中#.(sharpsign dot)作用及变量无值错误排查
错误定位与
#.语法说明 #.(sharpsign dot)的核心作用
#.是Common Lisp标准规定的读入期求值语法:Lisp读取器在解析源码、还未进入编译/运行阶段时,就会立即求值#.后跟随的表达式,将求值得到的常量结果直接替换到该语法所在的代码位置,后续代码运行过程中不会再重新计算这部分内容。
变量无值错误的根因
报错和loop与cond的交互、setf/let*/multiple-value-bind的作用域规则没有任何关系,完全是#.的误用导致的:
- 你在
output函数cond分支中写的#.(code-char (car (last bar-chars)))、#.(code-char (nth ... bar-chars))这类表达式,会在Lisp读取defun output这段源码的阶段就被执行求值。 - 这个阶段
let*绑定的bar-chars、内层循环中通过setf赋值的char-column/char-decimal都还不存在——这些变量都是代码运行到对应逻辑位置时才会创建的运行期绑定,读入阶段没有任何对应的变量定义,因此读取器求值时直接抛出变量无值的错误。 - 即便把
bar-chars替换为列表字面量,依然会报char-decimal无值错误,原因完全相同:char-decimal是循环运行时才会被赋值的变量,读入期求值时不可能访问到。
对应错误点的修正方向
只需要移除三个cond分支中code-char调用外层包裹的#.,让code-char的调用在代码运行阶段、相关变量已经完成绑定/赋值时再执行即可。
内容的提问来源于stack exchange,提问作者brubsby
相关产品推荐
相关产品推荐

