次の case ステートメントでは、x が #\j に設定されていますが、"bye" が返されます。
(case (find #\j "joy") ((x) (princ "hi")) (otherwise (princ "bye")))
find は #\j を返すはずですが、これは x と一致するはずですよね?
次の case ステートメントでは、x が #\j に設定されていますが、"bye" が返されます。
(case (find #\j "joy") ((x) (princ "hi")) (otherwise (princ "bye")))
find は #\j を返すはずですが、これは 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"
句キーは評価されないため、句((x)...)
は記号と一致しますx
。これがケースの要点です。キーは一定であるため、フォームをコンパイルしてより効率的なコードを生成できます。動的キーが必要な場合は、関連付けリスト、ハッシュテーブルなどを使用します。