Lisp 中的 Switch 语句

问题描述 投票:0回答:4

Lisp 中带有字符串的 Switch 语句。

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

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

switch-statement lisp common-lisp
4个回答
10
投票

print("XY")
看起来更像 Algol(及其所有 后代)而不是 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
以外的东西。例如。使用
cond
if
equal


10
投票

您可以使用库

alexandria
,它有一个可配置的
switch
宏:

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

4
投票

CASE 上的

Hyperspec
说:

这些宏允许有条件地执行子句中的表单主体,该子句是通过根据其身份匹配测试键来选择的。

并且 CL 中的字符串不相同,即

(EQ "AB" "AB") => NIL

这就是为什么

CASE

 不适用于字符串。您要么需要使用符号(它们仅被保留一次,从而保证身份),要么使用 
COND
EQUAL
 甚至 
EQUALP
(如果要忽略字母大小写)。


0
投票
现在您可以像这样使用

pcase

(defun switch(value) (pcase value ("XY" "xyxy") ("AB" "abab"))) switch (switch "XY") "xyxy" (switch "AB") "abab"
    
© www.soinside.com 2019 - 2024. All rights reserved.