Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Common lisp 使用“声明全局变量”;人工的;象征_Common Lisp - Fatal编程技术网

Common lisp 使用“声明全局变量”;人工的;象征

Common lisp 使用“声明全局变量”;人工的;象征,common-lisp,Common Lisp,所谓“人工”,我指的是使用intern或makesymbol从字符串创建的符号 我的代码中有一部分声明了多达49个全局变量: (defparameter *CHAR-COUNT-1-1* (make-hash-table)) ... (defparameter *CHAR-COUNT-1-7* (make-hash-table)) ... (defparameter *CHAR-COUNT-7-7* (make-hash-table)) 我想,相反,我可以创建一个函数来完成这一切: (loop

所谓“人工”,我指的是使用
intern
makesymbol
从字符串创建的符号 我的代码中有一部分声明了多达49个全局变量:

(defparameter *CHAR-COUNT-1-1* (make-hash-table))
...
(defparameter *CHAR-COUNT-1-7* (make-hash-table))
...
(defparameter *CHAR-COUNT-7-7* (make-hash-table))
我想,相反,我可以创建一个函数来完成这一切:

(loop for n from 1 to 7 do
  (loop for i from 1 to 7 do
    (defparameter (symbol-value (intern (concatenate 'string "*CHAR-COUNT-" (write-to-string n) "-" (write-to-string i) "*")))
                  (make-hash-table :test 'equalp))))
但是得到错误(sbcl):

线程中未处理的简单错误#:
无法将非符号声明为特殊:(symbol-VALUE)
(实习生)
(连接“字符串”*字符计数-
(写入字符串N)“-”
(写入字符串I)
"*")))

正确的方法是什么?

使用带有
DEFPARAMETER
stanzas的
PROGN
宏或“使用,它是一个函数,而不是宏”。

DEFPARAMETER是一个宏,而不是一个函数。这意味着它定义了一种特殊的语法。defparameter表单需要有一个符号作为其第二个参数,但您提供了以下列表:

(symbol-value (intern (concatenate 'string "*CHAR-COUNT-" (write-to-string n) "-" (write-to-string i) "*")))
你想要的是一个像

您似乎对循环和创建符号以创建该列表非常熟悉;换衣服

(loop … do (loop … do (defparameter …)))

你可以得到你需要的表格。然后,只需将其全部放入宏中即可

(defmacro … (…) 
  `(progn 
     ,@(loop … nconcing
         (loop … collecting
          `(defparameter ,(intern …) …)))))

和调用宏。

正确的方法是使用正确的数据结构,而不是用符号名对维度进行编码。您真的想在任何时候访问正确的表时计算和编码符号名称吗

(defparameter *char-counts* (make-array '(7 7)))

(dotimes (i 49) ; or (reduce #'* (array-dimensions *char-counts*))
  (setf (row-major-aref *char-counts* i) (make-hash-table)))
现在,您只需使用索引即可访问表数组(
x
y
,在本例中):


将维度信息嵌入变量名似乎应该是不同的数据结构,如二维数组。但如果你真的想这么做,一个简单的方法是通过macrolet;您不需要符号的值……您还需要宏扩展def参数。
`(progn 
  ,@(loop … nconcing
      (loop … collecting
        `(defparameter ,(intern …) …))))
(defmacro … (…) 
  `(progn 
     ,@(loop … nconcing
         (loop … collecting
          `(defparameter ,(intern …) …)))))
(defparameter *char-counts* (make-array '(7 7)))

(dotimes (i 49) ; or (reduce #'* (array-dimensions *char-counts*))
  (setf (row-major-aref *char-counts* i) (make-hash-table)))
(gethash (aref *char-counts* x y) :foo)