If statement if语句层的替代方法

If statement if语句层的替代方法,if-statement,lisp,boolean,conditional,If Statement,Lisp,Boolean,Conditional,有时,我会在lisp代码中使用多层if语句。除此之外还有其他选择吗 不幸的是,在这种情况下,答案是“视情况而定”。在某些情况下,明显的选择是使用cond (if condition1 result1 (if condition2 result2 default)) ;; naturally converted to: (cond (condition1 result1) (condition2 result2) (t defaul

有时,我会在lisp代码中使用多层if语句。除此之外还有其他选择吗

不幸的是,在这种情况下,答案是“视情况而定”。在某些情况下,明显的选择是使用
cond

(if condition1
   result1
   (if condition2
       result2
       default))

;; naturally converted to:
(cond (condition1 result1)
      (condition2 result2)
      (t default))
在其他时候,
cond
与一点
可能正是您想要的

(if condition1
   (if condition2
       result12
       result1)
   (if condition2
       result2
       default))

;; naturally turns intoteh answe
(cond ((and condition1 condition2) result12)
      (condition1 result1)
      (condition2 result2)
      (t default))
注意,我只写了这段代码,没有测试过,但原则上应该没问题


不幸的是,有时即使是稍微简单一点的
cond
表单也可能不够清晰,在这种情况下,通常也值得更努力地关注实际问题。可能有一种方法可以更好地分解逻辑(调度表、具有合适参数的外部逻辑调用函数等)。

不幸的是,在这种情况下,答案是“它取决于”。在某些情况下,明显的选择是使用
cond

(if condition1
   result1
   (if condition2
       result2
       default))

;; naturally converted to:
(cond (condition1 result1)
      (condition2 result2)
      (t default))
在其他时候,
cond
与一点
可能正是您想要的

(if condition1
   (if condition2
       result12
       result1)
   (if condition2
       result2
       default))

;; naturally turns intoteh answe
(cond ((and condition1 condition2) result12)
      (condition1 result1)
      (condition2 result2)
      (t default))
注意,我只写了这段代码,没有测试过,但原则上应该没问题


不幸的是,有时即使是稍微简单一点的
cond
表单也可能不够清晰,在这种情况下,通常也值得更努力地关注实际问题。可能有一种方法可以更好地分解逻辑(调度表、具有适当参数的外部逻辑调用函数等)。

您可以在几个方向上更改代码

  • 创建封装条件的高阶函数,或者宏,或者重用现有宏(举个例子)
    remove if
    是一个高阶函数的示例,它可以避免您编写“if”

  • 使用多态性。Lisp有类、对象、重载和所有您期望对象系统拥有的工具(甚至可能有一点额外的;)

  • 假设您有以下代码:

    ;; Suppose your `person' is a list that has that person's
    ;; name as its first element:
    
    (defun hello! (person)
      (if (string= (car person) "John")
            (concatenate 'string "Hello, " (car person))
         (print "Hello, who are you?")))
    
    (defun goodbye! (person)
      (if (string= (car person) "John")
            (concatenate 'string "Goodbye, " (car person))
         (print "Goodbye, mysterious stranger!")))
    
    ;; You would use it like so:
    (hello! '("John" x y z))
    (goodbye! '(nil x y z))
    
    现在,您可以将其改写为:

    (defclass person () ())
    
    (defclass friend (person)
      ((name :accessor name-of
             :initarg :name)))
    
    (defgeneric hello! (person))
    (defgeneric goodbye! (person))
    
    (defmethod hello! ((person person))
      (print "Hello, who are you?"))
    
    (defmethod hello! ((person friend))
      (print (concatenate 'string "Hello, " (name-of person))))
    
    (defmethod goodbye! ((person person))
      (print "Goodbye, mysterious stranger!"))
    
    (defmethod goodbye! ((person friend))
      (print (concatenate 'string "Goodbye, " (name-of person))))
    
    ;; Which you would use like so:
    
    (hello! (make-instance 'person))
    (goodbye! (make-instance 'friend :name "John"))
    
    ;; Note that however the later is significantly more verbose
    ;; the ratio will change when you have more `if's which you
    ;; can systematize as objects, or states.
    

    换句话说,通过封装状态,可以避免显式编写条件语句。您还可以在过程中获得一些可读性,因为您不需要记住列表中的哪一部分包含哪些信息-您现在可以将其标记为“名称”。

    更改代码的方向很少

  • 创建封装条件的高阶函数,或者宏,或者重用现有宏(举个例子)
    remove if
    是一个高阶函数的示例,它可以避免您编写“if”

  • 使用多态性。Lisp有类、对象、重载和所有您期望对象系统拥有的工具(甚至可能有一点额外的;)

  • 假设您有以下代码:

    ;; Suppose your `person' is a list that has that person's
    ;; name as its first element:
    
    (defun hello! (person)
      (if (string= (car person) "John")
            (concatenate 'string "Hello, " (car person))
         (print "Hello, who are you?")))
    
    (defun goodbye! (person)
      (if (string= (car person) "John")
            (concatenate 'string "Goodbye, " (car person))
         (print "Goodbye, mysterious stranger!")))
    
    ;; You would use it like so:
    (hello! '("John" x y z))
    (goodbye! '(nil x y z))
    
    现在,您可以将其改写为:

    (defclass person () ())
    
    (defclass friend (person)
      ((name :accessor name-of
             :initarg :name)))
    
    (defgeneric hello! (person))
    (defgeneric goodbye! (person))
    
    (defmethod hello! ((person person))
      (print "Hello, who are you?"))
    
    (defmethod hello! ((person friend))
      (print (concatenate 'string "Hello, " (name-of person))))
    
    (defmethod goodbye! ((person person))
      (print "Goodbye, mysterious stranger!"))
    
    (defmethod goodbye! ((person friend))
      (print (concatenate 'string "Goodbye, " (name-of person))))
    
    ;; Which you would use like so:
    
    (hello! (make-instance 'person))
    (goodbye! (make-instance 'friend :name "John"))
    
    ;; Note that however the later is significantly more verbose
    ;; the ratio will change when you have more `if's which you
    ;; can systematize as objects, or states.
    

    换句话说,通过封装状态,可以避免显式编写条件语句。您还可以在途中获得一些可读性,因为您不需要记住列表中的哪一部分包含哪些信息-您现在可以将其标记为“名称”。

    谢谢,虽然有些抽象,但这似乎非常强大。我会花些时间来消化和应用这个。谢谢你,虽然有点抽象,但它似乎非常强大。我会花时间去消化和应用这些。