我意识到这可能是一个非常愚蠢的问题,但我不知道为什么这不起作用,我几乎放弃了。基本上我试过了:
(setq answer (string (read)))
和
(setq answer 0)
(format answer "~s" (read))
和
(setq answer (read))
当我尝试评估时
(if (stringp answer)
(princ "works")
(princ "failed"))
在任何上述尝试中总是失败。
我做错了什么?
答案 0 :(得分:20)
或者你可以这样做:
(setq answer (read-line))
那就给你一个字符串。
[1]> (setq answer (read))
3
3
[2]> (type-of answer)
(INTEGER 0 16777215)
[3]> (setq answer (read-line))
3
"3"
[4]> (type-of answer)
(SIMPLE-BASE-STRING 1)
[5]>
答案 1 :(得分:5)
启动一个新的REPL,然后尝试检查每个步骤的返回值:
T1> (read)
foo
FOO
T1> (read)
1
1
T1> (type-of (read))
foo
SYMBOL
T1> (type-of (read))
1
BIT
现在请注意,STRING
不适用于所有输入类型:
T1> (string 'foo)
"FOO"
T1> (string 1)
另请注意,与setq
不同,(format foo ...)
不会设置 foo
,而是写入,如果它是stream或一个string fill-pointer。看看它的Documentation,你会看到:
格式化目标控制字符串 & rest args =>结果
[...]
目的地--- nil,t,流或a 带填充指针的字符串。
[...]
格式对于很好地生成很有用 格式化文本,产生好看 消息,等等。格式可以 生成并返回一个字符串或输出 到目的地。
如果destination是一个字符串,一个流, 或者t,结果是零。 否则,结果是一个字符串 包含`output。'
试试这样:
T1> (setq *answer*
(with-output-to-string (s)
(format s "~s" (read))))
1
"1"
T1> *answer*
"1"
或者像这样:
T1> (setq *answer* (make-array 20 :element-type 'character :fill-pointer 0))
""
T1> (format *answer* "~s" (read))
1
NIL
T1> *answer*
"1"
这些是我在代码中找到的唯一相关错误。这肯定会在每个符合要求的CL中返回"works"
(您也可以使用prin1-to-string
):
T1> (defvar *answer*)
*ANSWER*
T1> (setq *answer* (format nil "~s" (read)))
1
"1"
T1> (if (stringp *answer*)
(princ "works")
(princ "failed"))
works
"works"
除非您处于混乱的程序包中(在评估代码之前尝试(in-package cl-user)
)或重新定义基本功能,否则这将起作用。如果仍然没有,请提供更准确的错误描述。
ED:
读过Bill的回答,他正确指出read-line
是一个较短的解决方案,我应该提一下,我并没有试图在我的回答中展示最好,最简洁或最惯用的方法,而且这取决于你真正想做的事情。 (最短的解决方案可能是"works"
:)它们只是帮助解释代码失败原因的示例。
我忘了说的另一件事是你应该记住,在setq
或defvar
未定义的变量上defparameter
通常应该避免在任何事情上进行调整在REPL,因为后果不明确。此外,按照惯例,这些变量包含在星号(也称为 earmuffs )中,以防止因使用词法范围变量混淆特殊错误而导致的错误。