在下面的case語句中,x被設置爲#\ j,但返回「bye」。爲什麼沒有找到返回元素作爲案例的關鍵?
(case (find #\j "joy") ((x) (princ "hi")) (otherwise (princ "bye")))
發現應該返回#\ j,它應該匹配x,對吧?
在下面的case語句中,x被設置爲#\ j,但返回「bye」。爲什麼沒有找到返回元素作爲案例的關鍵?
(case (find #\j "joy") ((x) (princ "hi")) (otherwise (princ "bye")))
發現應該返回#\ j,它應該匹配x,對吧?
子句鍵不會被評估,所以子句((x)...)
只會匹配符號x
。這是案例的整點:密鑰是不變的,因此表單可以被編譯以產生更高效的代碼。如果你想要動態密鑰然後使用關聯列表,散列表等。
讓我們來看看。
CL-USER 2 > (setf x #\j)
#\j
CL-USER 3 > (case (find #\j "joy") ((x) (princ "hi")) (otherwise (princ "bye")))
bye
"bye"
簡化:讓我們擺脫FIND
。
CL-USER 4 > (case #\j ((x) (princ "hi")) (otherwise (princ "bye")))
bye
"bye"
不起作用。簡化:請勿PRINC
。
CL-USER 5 > (case #\j ((x) (princ "hi")) (otherwise "bye"))
"bye"
不起作用。簡化:請勿PRINC
。
CL-USER 6 > (case #\j ((x) "hi") (otherwise "bye"))
"bye"
不起作用。我們有一個小表情。 CASE
是一個宏。讓我們擴展形式:
CL-USER 7 > (macroexpand '(case #\j ((x) "hi") (otherwise "bye")))
(LET ((#:G1084 #\j))
(COND ((OR (EQL (QUOTE X) #:G1084)) "hi")
(T "bye")))
T
哦,X
被引用,而不是評估。因此,您正在測試字符#\j
是否等於符號X
。這失敗了。
CASE
不評估密鑰。
解決方案:使用類似COND
的東西或編寫一個隱藏類似COND
之類的宏。這已被多次寫成練習。
CL-USER 8 > (let ((value (find #\j "joy")))
(cond ((eql value x) "hi")
(t "bye")))
"hi"