微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Common Lisp 中的重复 case 语句

如何解决Common Lisp 中的重复 case 语句

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

(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*)

在 Python 中,我会为此使用 case 1..4,在 C++、Java 和 co 中。我可能会使用 falltrough 开关案例,其中我省略案例 1 到案例 3 的中断。在没有代码重复的 clisp 中是否有一个巧妙的小技巧?

解决方法

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

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
,

一个 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"))))

如果手动填写范围太麻烦,请说 1 to 100,最好使用 cond 代替:

(cond
  ((<= 1 age 100) 'one-to-ahundred)
  ;; ...and so on.
  )

不过,您可能使用阅读器宏。不过,我认为我个人不会走这条路线:

(case age
  ;; with vanilla Common Lisp.
  (#.(loop :for x :from 1 :upto 100 :collect x) 'one-to-ahundred)
  ;; or,with Alexandria's iota:
  (#.(alexandria:iota 100 :start 101) 'hundredandone-to-twohundred)

  ;; ...and so on.
  )
,

您可以像这样使用 condmember

(defun age-test ()
  (format t "Enter your age: ~%")
  (finish-output)
  (let ((age (read)))
    (format t (cond ((member age '(1 2 3 4)) "You belong in Kindergarden~%")
                    ((= age 5) "You belong in Preschool~%")
                    ((= age 6) "Elementary school ~%")
                    (t "Somewhere else")))))

(age-test)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。