由两个竖线括起来的关键字符号
keyword symbol enclosed by two pipes
假设下面代码中有一个函数fun
,我的目标是在下面计算expr2
。
(defun fun (&key (x nil)) x)
(defparameter expr1 (list 'fun :x 2))
(defparameter expr2 (list 'fun (intern "x" "KEYWORD") 2))
正如预期的那样,(eval expr1)
给出了 2
,但是 (eval expr2)
给出了类似
的错误
*** - FUN: illegal keyword/value pair :|x|, 2 in argument list.
The allowed keywords are (:X) The following restarts are available: ABORT :R1 Abort main loop
为什么会出现这个错误?以及如何修复它?
原因是通常在 Common Lisp 中,每个符号在读取时都会被翻译成大写字母(这是标准行为,可以更改),因此:
(defun fun (&key (x nil)) x)
(defparameter expr1 (list 'fun :x 2))
实际读作:
(DEFUN FUN (&KEY (X NIL)) X)
(DEFPARAMETER EXPR1 (LIST 'FUN :X 2))
而 intern
获取一个字符串作为第一个参数并且不对其进行转换,因此在您的示例中 "x" 被保留为符号 :x
,这与符号不同:X
(这就是错误的原因)。请注意,当在 REPL 中打印带有小写字母的符号时,它会被管道字符 (|
) 包围,就像在 |x|
中一样,因此,当再次读取时,小写字符不会发生变化:
CL-USER> :x
:X
CL-USER> :|x|
:|x|
CL-USER> (format t "~a" :|x|)
x
NIL
要解决你的问题,你可以直接将字符串写成大写:
(defparameter expr2 (list 'fun (intern "X" "KEYWORD") 2))
然后 (eval expr2)
按预期工作。
注意\
和|
是符号中的转义字符:
? 'foo\xBAR
FOO\xBAR
? '|This is a symbol|
|This is a symbol|
? ':|This is a keyword symbol with spaces and Capital letters!!!|
:|This is a keyword symbol with spaces and Capital letters!!!|
? 'what|? wow |this| also works|?
|WHAT? wow THIS also works?|
假设下面代码中有一个函数fun
,我的目标是在下面计算expr2
。
(defun fun (&key (x nil)) x)
(defparameter expr1 (list 'fun :x 2))
(defparameter expr2 (list 'fun (intern "x" "KEYWORD") 2))
正如预期的那样,(eval expr1)
给出了 2
,但是 (eval expr2)
给出了类似
*** - FUN: illegal keyword/value pair :|x|, 2 in argument list. The allowed keywords are (:X) The following restarts are available: ABORT :R1 Abort main loop
为什么会出现这个错误?以及如何修复它?
原因是通常在 Common Lisp 中,每个符号在读取时都会被翻译成大写字母(这是标准行为,可以更改),因此:
(defun fun (&key (x nil)) x)
(defparameter expr1 (list 'fun :x 2))
实际读作:
(DEFUN FUN (&KEY (X NIL)) X)
(DEFPARAMETER EXPR1 (LIST 'FUN :X 2))
而 intern
获取一个字符串作为第一个参数并且不对其进行转换,因此在您的示例中 "x" 被保留为符号 :x
,这与符号不同:X
(这就是错误的原因)。请注意,当在 REPL 中打印带有小写字母的符号时,它会被管道字符 (|
) 包围,就像在 |x|
中一样,因此,当再次读取时,小写字符不会发生变化:
CL-USER> :x
:X
CL-USER> :|x|
:|x|
CL-USER> (format t "~a" :|x|)
x
NIL
要解决你的问题,你可以直接将字符串写成大写:
(defparameter expr2 (list 'fun (intern "X" "KEYWORD") 2))
然后 (eval expr2)
按预期工作。
注意\
和|
是符号中的转义字符:
? 'foo\xBAR
FOO\xBAR
? '|This is a symbol|
|This is a symbol|
? ':|This is a keyword symbol with spaces and Capital letters!!!|
:|This is a keyword symbol with spaces and Capital letters!!!|
? 'what|? wow |this| also works|?
|WHAT? wow THIS also works?|