我在常见的lisp中编写了这段代码(忽略了......因为在这里粘贴该部分毫无意义)。
(case turn
(*red-player* ...)
(*black-player* ...)
(otherwise ...))
red-player 和 black-player 是使用defvar语句定义的变量,以便在C中“模拟”#define语句。
(defvar *red-player* 'r)
(defvar *black-player* 'b)
可以想象,当变量turn
收到*red-player*
的值('r)或*black-player*
的值('b)时,case语句不会正常工作,因为它希望转弯包含*red-player*
作为文字,而不是变量*red-player*
的内容。
我知道我可以使用cond或if + equal语句轻松修复它,因为变量的内容在那里被评估,但我很好奇。也许有一种方法可以在Lisp中创建类似C的宏,或者有某种特殊的case语句允许使用变量而不是文字。
提前谢谢!
答案 0 :(得分:5)
您可以使用阅读时评估
在表单中输入表达式的值CL-USER 18 > (defvar *foo* 'a)
*FOO*
CL-USER 19 > (defvar *bar* 'b)
*BAR*
CL-USER 20 > '(case some-var (#.*foo* 1) (#.*bar* 2))
(CASE SOME-VAR (A 1) (B 2))
请注意,读取时评估不一定是改善代码维护和安全性的最佳选择。
另请注意,在Lisp中不需要有一个带有某个内部值的描述性名称的变量的想法:
dashedline = 4
drawLine(4,4,100,100,dashedline)
将在Lisp中
(draw-line 4 4 100 100 :dashed-line)
在Lisp中,可以传递描述性命名的符号。使用整数值或类似值的API只需要在API中使用通常用C语言编写的外部软件。
答案 1 :(得分:4)
简短的回答是“是的,你可以做到,有点像”。
更长答案的种子涉及使用defmacro
创建自己的case
版本,比如mycase
,这将返回常规的case
表单。您定义的宏将评估案例正文中每个列表的头部。
你会打电话:
(mycase turn
(*red* ...)
(*black* ...)
(otherwise ...))
会返回
(case turn
((r) ...)
((b) ...)
(otherwise ...))
给评估员。然后,将以您希望的方式评估返回的case
表单。
然后,您可以自由地继续使用您的c-esque方式编程,让各地的lispers感到沮丧!双赢?
答案 2 :(得分:2)
您可以以任何您喜欢的方式滥用Lisp。与C不同,它很灵活。
它并不总是喜欢您使用它的用途。为什么要把Lisp推到一边?
尝试这种方法:
(defvar *turn* nil)
(cond
((eq *turn* 'red)
...
(setq *turn* 'black)))
((eq *turn* 'black)
...
(setq *turn* 'red)))
(t
.......))