3

在python中可以做到这一点

EMPTY, PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING, BPAWN = range(8)

你会如何在 lisp 中做等价?

4

7 回答 7

10

在 Lisp 中只使用符号会更惯用。通常作为自我评估的关键字符号:

(defparameter *chess-pieces*
  '(:EMPTY :PAWN :KNIGHT :BISHOP :ROOK :QUEEN :KING :BPAWN))

定义数值是有原因的——有时。尤其是当您需要与外国功能交谈时。在 Lisp 中,你会默认使用符号。

Common Lisp 没有真正的枚举类型。在动态类型语言中使用符号比使用数字变量有一些优势。例如,在调试期间,变量内容更具描述性:

相比:

> (setf c4 queen)

> c4
6

对比

> (setf c4 :queen)

> c4
:queen

在后一个示例中,符号值是自描述的。

于 2012-06-03T18:36:18.110 回答
4

假设您已经在range某处 ( (defun range (n) (loop :for i :from 0 :below n :collect i))) 定义了便捷函数,您可以设置一些局部值,如下所示:

(destructuring-bind (EMPTY PAWN KNIGHT BISHOP ROOK QUEEN KING BPAWN)
    (range 8)
  #| do stuff |#)

然而,像这样的枚举很少在 Lisp 代码中使用,因为关键字(或其他符号)提供了类似的功能。

于 2012-06-03T16:34:00.970 回答
2

写一个宏来做到这一点怎么样?一个例子:

(defmacro defenum (&rest args)
  (let ((counter 0))
    `(progn
       ,@(mapcar (lambda (arg)
                   (cond ((symbolp arg)
                          (prog1
                              `(defparameter ,arg ,counter)
                            (incf counter)))
                         ((listp arg)
                          (prog1
                              `(defparameter ,(first arg) ,(second arg))
                            (setf counter (1+ (second arg)))))
                         (t (error "broken defenum"))))
                 args))))

使用示例:

(defenum x (y 2) z)

(defenum EMPTY PAWN KNIGHT BISHOP ROOK QUEEN KING BPAWN)

(在这个例子上改进可能很容易:-) - 我更喜欢defparameter这样defconstant你可能想要改变的东西)

于 2012-06-03T16:23:29.877 回答
0

这是一种方法:

(let ((c 0))
  (dolist (piece '(EMPTY PAWN KNIGHT BISHOP ROOK QUEEN KING BPAWN))
    (eval `(defconstant ,piece ,c)) 
    (incf c)))
于 2012-06-03T23:51:37.790 回答
0

使用默认常量:

 (defconstant name initial-value-form [ documentation-string ])

例如:

(defconstant myvar 5)
于 2012-06-03T13:42:38.757 回答
0

我曾经这样做的简单宏:

(defmacro enum-constants (&rest constants)
 `(progn ,@(mapcar #'(lambda (key value) `(defconstant ,key ,value))
                   constants (loop for i from 0 below (length constants) collecting i))))
于 2021-04-13T12:41:30.193 回答
0

可以macrolet用来计算设置一堆常量的形式:

(macrolet ((defenumvalues (&rest names)
             `(progn
                ,@(loop for n in names and i from 0
                        collect `(defconstant ,n ,i))
                (values))))
  (defenumvalues empty pawn knight bishop rook queen king bpawn))

替代方案:使用 . 编写全局宏defmacro

使用宏(局部或全局)定义一堆常量的一般优势:编译器扩展表达式,然后看到一堆cl:defconstant形式。

于 2018-05-05T15:03:51.100 回答