Lisp-如果声明各种动作

MinSeob Lim

这是我的Lisp代码。

 (DEFUN F (A B)
              (SETF C (* 4 A))
              (SETF D (* 2 (EXPT B 3)))
              (SETF RES (+ C D))
              (IF (AND (TYPEP A 'INTEGER) (TYPEP B 'INTEGER))
                  (list 'Final 'value '= res)
                '(YOUR INPUTS ARE NOT NUMBERS)))

例如,(f 5 9)效果很好。(f 'w 'q)不适用于以下错误消息:

(错误类型错误基准W期望类型编号的格式控制〜@ < ~s' is not of the expected type〜s'〜:@>格式参数(W编号))错误:W' is not of the expected typeNUMBER'

我想让A,B为整数,计算4A + 2B ^ 3。

否则,如果至少一个不是整数打印错误消息。

我尝试上面显示的代码。但是,如何使用if语句进行此错误处理?

吉斯基

首先,您应该使用LETLET*定义局部变量。

(defun f (a b)
  (let* ((c (* 4 a))           ; You need LET* instead of LET because
         (d (* 2 (expt b 3)))  ; RES depends on the previous variables.
         (res (+ c d)))
    (if (and (typep a 'integer) (typep b 'integer))
        (list 'final 'value '= res)
        '(your inputs are not numbers))))

实际的问题是,在检查参数是否为整数之前,您正在执行计算。您应该将计算移入IF

(defun f (a b)
  (if (and (integerp a) (integerp b))
      (let* ((c (* 4 a))
             (d (* 2 (expt b 3)))
             (res (+ c d)))
        (list 'final 'value '= res))
      '(your inputs are not numbers)))

这样返回列表有点奇怪。如果要将它们用作用户的输出,则应打印消息并返回实际结果。

(defun f (a b)
  (if (and (integerp a) (integerp b))
      (let ((result (+ (* 4 a)
                       (* 2 (expt b 3)))))
        (format t "Final value = ~a~%" result)
        result)                                      ; Return RESULT or
      (format t "Your inputs are not integers.~%"))) ; NIL from FORMAT.

在大多数情况下,如果参数不是正确的类型,则应发出错误信号。从执行计算的函数中打印输出通常是一个坏主意。

(defun f (a b)
  (check-type a integer "an integer")
  (check-type b integer "an integer")
  (+ (* 4 a)
     (* 2 (expt b 3))))

(defun main (a b)
  (handler-case
      (format t "Final value = ~a~%" (f a b))
    ;; CHECK-TYPE signals a TYPE-ERROR if the type is not correct.
    (type-error () (warn "Your inputs are not integers."))))

(main 12 1)
; Final value = 50
;=> NIL
(main 12 'x)
; WARNING: Your inputs are not integers.
;=> NIL

Common Lisp条件系统还允许您使用重新启动来修复错误。CHECK-TYPE建立名为的重新启动STORE-VALUE,您可以调用该重新启动来提供该地点的正确值。在这种情况下,这可能没有意义,但是您可以将use1用作默认值。

(defun main (a b)
  (handler-bind ((type-error (lambda (e)
                               (store-value 1 e))))
    (format t "Final value = ~a~%" (f a b))))

(main 12 1)
; Final value = 50
;=> NIL
(main 12 'x)
; Final value = 50
;=> NIL

请注意,条件/错误处理程序确实会增加一些开销,因此对于性能至关重要的函数,您可能不希望使用它们,而是在调用函数之前先检查参数。

(declaim (ftype (function (integer integer) integer) f))
(defun f (a b)
  (declare (optimize (speed 3) (safety 0) (debug 0)))
  (+ (* 4 a)
     (* 2 (expt b 3))))

(defun main (a b)
  (if (and (integerp a)
           (integerp b))
      (format t "Final value = ~a~%" (f a b))
      (warn "Your inputs are not integers.")))

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章