Common Lisp 中的重复 case 语句

L0r*_*en2 2 common-lisp

这里必须有更好的方法来做到这一点,对吗?

(format t "Enter your age: ~%")

(defun age-case (age)
  (case age
    (1 (format t "You belong in Kindergarden~%"))
    (2 (format t "You belong in Kindergarden~%"))
    (3 (format t "You belong in Kindergarden~%"))
    (4 (format t "You belong in Kindergarden~%"))
    (5 (format t "You belong in Preschool~%"))
    (6 (format t "Elementary school ~%"))
    (t (format t "Somewhere else"))))

(defvar *age* (read))

(age-case *age*)
Run Code Online (Sandbox Code Playgroud)

在 Python 中,我会为此使用 case 1..4,在 C++、Java 和 co 中。我可能会使用falltrough switch case,在这种情况下我省略了case 1到3的break。在clisp中是否有一个巧妙的小技巧可以在没有代码重复的情况下做到这一点?

Rai*_*wig 7

另一种选择是使用类型说明符:

CL-USER > (let ((age 6))
            (typecase age
              ((integer 1 4) 'one-to-four)   ; integers from 1 to 4
              ((eql 5)       'five)
              ((eql 6)       'six)
              (t             'something-else)))
SIX
Run Code Online (Sandbox Code Playgroud)


Sam*_*ter 5

一个case子句可以接受多个键:

(defun age-case (age)
  (case age
    ((1 2 3 4) (format t "You belong in Kindergarden~%"))
    (5 (format t "You belong in Preschool~%"))
    (6 (format t "Elementary school ~%"))
    (t (format t "Somewhere else"))))
Run Code Online (Sandbox Code Playgroud)

Rainer 的解决方案使用了integer类型中提供的范围typecase

(typecase age
  ((integer 1 4) 'one-to-four)
  ((eql 5)       'five)
  ((eql 6)       'six)
  (t             'something-else)))
Run Code Online (Sandbox Code Playgroud)

在此基础上,您可以“免费”进行类型检查:

(etypecase age
  ((integer 1 4) 'one-to-four)
  ((eql 5)       'five)
  ((eql 6)       'six)
  ((integer 7 *) 'something-else)))
Run Code Online (Sandbox Code Playgroud)

或者,您也可以使用cond

(typecase age
  ((integer 1 4) 'one-to-four)
  ((eql 5)       'five)
  ((eql 6)       'six)
  (t             'something-else)))
Run Code Online (Sandbox Code Playgroud)