【发布时间】:2008-10-17 10:54:37
【问题描述】:
Common Lisp 中是否有一个函数可以将字符串作为参数并返回关键字?
示例:(keyword "foo") -> :foo
【问题讨论】:
标签: common-lisp
Common Lisp 中是否有一个函数可以将字符串作为参数并返回关键字?
示例:(keyword "foo") -> :foo
【问题讨论】:
标签: common-lisp
给出的答案虽然大致正确,但并不能产生问题示例的正确解决方案。
考虑:
CL-USER(4): (intern "foo" :keyword)
:|foo|
NIL
CL-USER(5): (eq * :foo)
NIL
通常你想在实习之前将 STRING-UPCASE 应用于字符串,因此:
(defun make-keyword (name) (values (intern (string-upcase name) "KEYWORD")))
【讨论】:
:downcase...
这是一个 make-keyword 函数,它将关键字创建过程打包(interning 将名称放入 KEYWORD 包中)。 :-)
(defun make-keyword (name) (values (intern name "KEYWORD")))
【讨论】:
(symbol-value (intern "FOO" "KEYWORD")) 已经有了正确的值。此外,Alexandria 也使用相同的方法实现它。
Alexandria 库中有一个 make-keyword 函数,尽管它确实保留了大小写,因此要准确获得您想要的内容,您必须先将字符串大写。
【讨论】:
print-case 设置为:downcase。 intern 不做任何大小写修改,所以这里的解决方案可能也不应该。 (虽然问题中的示例确实说(keyword "foo") => :foo,但最好使用(... "foo") => :|foo| 或(... "FOO") => :FOO。)
在此示例中,它还处理带有空格的字符串(用点替换它们):
(defun make-keyword (name) (values (intern (substitute #\. #\space (string-upcase name)) :keyword)))
【讨论】:
"foo bar" 你会得到一个名为 "foo bar" 的符号,这没有问题。 intern 也不用点替换空格。
如果您可以将字符串更改为以冒号开头:
直接使用read-from-string。
这里是另一个版本的make-keyword:
(defun make-keyword (name)
(read-from-string (concatenate 'string ":" name)))
【讨论】:
(read-from-string (concatenate 'string ":" name))吗?
(intern "foo" "KEYWORD") -> :foo
请参阅Common Lisp Cookbook 的Strings section 了解其他字符串/符号转换以及符号和包的详细讨论。
【讨论】: