如何停止从 LISP 中的 if 语句获取 NIL

How to stop getting NIL from if statement in LISP

很抱歉问这个问题,但我正在学习 LISP 中的可选参数 因此,我创建了一个名为“calculate-bill”的函数,它将采用两个参数:

所以你可以猜到,如果折扣被传递给函数,它会从金额中减去它的值,否则只打印金额。

代码:

(defun calculate-bill (amount &optional discount)
  (if (null discount)
    (format t "Total bill is ~d." amount))
  (if discount
    (format t "Total bill is ~d." (- amount discount))))

(write (calculate-bill 200 50))
(terpri)
(write (calculate-bill 200))

这里我在 if 块中添加了 null 条件。

我希望我的预期输出是:

Total bill is 150.
Total bill is 200.

但是当前输出是:

Total bill is 150.NIL
Total bill is 200.NIL

如何避免“NIL”?

你在做双输出。您调用 FORMAT 和 WRITE。

现在你需要弄清楚你是否真的想做双输出,如果不是,哪些功能要保留,哪些不要。

函数 calculate-bill 打印出消息“总量是...”,但这只是一个 副作用 。函数编辑的valuereturn是,当没有显式return <value>时,最后执行的函数的值,在本例中是format,当输出流为 T 时,format 的值始终为 nil。因此 write 函数所做的是打印由 calculate-bill 编辑的值为 nil 的 return。如果你想要 calculate-bill 到 return 字符串然后将格式的输出流更改为 nil:

(format nil "Total bill is ~d." amount)

这会创建一个字符串,直到您将其传递给输出函数(例如write.

额外建议,函数if可以带三个参数:测试,测试为t时执行的代码,测试为nil时执行的代码。所以,在你的情况下,最好写成:

(if (null discount)
    (format t "Total bill is ~d." amount)
    (format t "Total bill is ~d." (- amount discount)))

可选参数接受默认值,例如您可以将默认折扣设置为零。

(defun calculate-bill (amount &optional (discount 0))
  (check-type discount real)
  (- amount discount))

选择默认折扣 0 然后保存 null 测试。

此外,我会 formatnil 到 return 字符串。

(defun calculate-bill (amount &optional (discount 0))
  (format nil "Total bill is ~d." (- amount discount)))

write 打印和 returns。只有通过 (format t "~a" x).

实现的打印
(progn 
  (format t "~a" (calculate-bill 200 50)) 
  (terpri) 
  (format t "~a" (calculate-bill 200)))

或者,您可以将 "~%" 包含到 format 字符串中,而不是使用 (terpri).

(progn 
  (format t "~a~%" (calculate-bill 200 50)) 
  (format t "~a~%" (calculate-bill 200)))

我可以选择让显示结果但 return 字符串。

(defun calculate-bill (amount &key (discount 0) (verbosep nil))
  (let* ((result (- amount discount))
        (res (format nil "Total bill is ~d." result)))
    (if verbosep
      (format t "~a~%" res))
    res))

然后设置 :verbosep t 如果您希望输出在终端中可见。

(calculate-bill 200 :discount 50 :verbosep t)
(calculate-bill 200 :verbosep t)