Lisp 中的 switch 语句

Switch statement in Lisp

在 Lisp 中使用字符串切换语句。

    (defun switch(value) 
      (case value
        (("XY") (print "XY"))
        (("AB") (print "AB"))
      )
    ) 

我想比较值是否为 "XY" 然后打印 "XY" 或 "AB" 相同。 我试过这段代码,但它给了我零。有人可以告诉我我做错了什么吗?

print("XY") 看起来更像 Algol(及其所有 descendants)而不是 LISP。要应用 print,可以将运算符和参数括在括号中,例如 (print "XY")

case 恰好是一个宏,您可以通过将引用的代码传递给 macroexpand 来自己测试结果,在我的实现中我得到:

(let ((value value)) 
  (cond ((eql value '"XY") (print "XY")) 
        ((eql value '"AB") (print "AB"))))

您应该知道 eql 仅适用于原始数据类型和数字。字符串是序列,因此 (eql "XY" "XY") ;==> nil

也许你应该使用 case 以外的东西。例如。使用 condifequal.

您可以使用库 alexandria,它有一个可配置的 switch 宏:

(switch ("XY" :test 'equal)
  ("XY" "an X and a Y")
  ("AB" "an A and a B"))

CASE 上的 Hyperspec 说:

These macros allow the conditional execution of a body of forms in a clause that is selected by matching the test-key on the basis of its identity.

并且字符串在 CL 中不相同,即 (EQ "AB" "AB") => NIL

这就是 CASE 不适用于字符串的原因。您要么需要使用符号(它们只被实习一次,从而保证身份),要么使用 CONDEQUAL 甚至 EQUALP 如果要忽略字母大小写。