'A'不是预期类型'REAL'

Alv*_*uan 1 lisp

服务器下面的代码显示列表中的整数.

(defun isNum (N)
  (and (<= N 9) (>= N 0)))

(defun count-numbers (list)
  (let ((count 0))
    (dolist (item list count)
      (cond
       ((null list) nil)
       (((and (<= N 9) (>= N 0))) item)(incf count))
       (setq(0 + count))))))
Run Code Online (Sandbox Code Playgroud)

A' is not of the expected type运行命令时得到错误REAL'(count-numbers'(3 4 5 6 a 7 b))

Ina*_*thi 6

我对它的运行感到惊讶,因为你cond的构造不正确,你在代码的不必要的副作用生成位中切换到中缀符号,并且你正在使用未绑定的变量count-numbers.假设,如果它确实运行,那么这个错误听起来是正确的.您正在对参数进行数值比较(以及非数字输入上的错误).

今天我已经有了我的代码审查帽,所以让我们更深入地讨论这个问题.


Lisp(它实际上并不重要,这适用于CL,Scheme和所有的mongrels)lower-case-snake-case-with-dashes,而不是lowerCamelCase变量和函数名称.

(defun is-num (n)
  (and (<= n 9) (>= n 0)))
Run Code Online (Sandbox Code Playgroud)

Common Lisp约定是用p-p不用它来开始谓词is-.计划有结束的谓词(IMO更好)约定?代替

(defun num-p (n)
  (and (<= n 9) (>= n 0)))
Run Code Online (Sandbox Code Playgroud)

((and (<= N 9) (>= N 0)))不是你怎么称呼一个功能.你实际上需要使用它的名字,而不仅仅是试图调用它的身体.如果您尝试运行此代码,则会出现许多错误之一.

(defun count-numbers (list)
  (let ((count 0))
    (dolist (item list count)
      (cond
       ((null list) nil)
       ((num-p item) item)(incf count))
       (setq(0 + count))))))
Run Code Online (Sandbox Code Playgroud)

numberp已存在,并对其输入进行类型检查,而不是尝试进行数字比较.您可能应该使用它.

(defun count-numbers (list)
  (let ((count 0))
    (dolist (item list count)
      (cond
       ((null list) nil)
       ((numberp item) item)(incf count))
       (setq(0 + count))))))
Run Code Online (Sandbox Code Playgroud)

((numberp item) item) (incf count))可能不会做你认为它作为一个cond条款.它实际上被视为两个单独的条款; 一个检查是否item为a number,如果是则返回.第二个尝试检查变量incf并返回count它是否计算结果t(它不会,也不会).你似乎想要的是count当你在列表中找到一个数字时增加计数器,这意味着你应该将该incf子句放入item.

(defun count-numbers (list)
  (let ((count 0))
    (dolist (item list count)
      (cond ((null list) nil)
            ((numberp item) 
             (incf count)
             item))
      (setq (0 + count)))))
Run Code Online (Sandbox Code Playgroud)

(setq (0 + count)) 出于三个原因是错误的

  • 你似乎已经重新进入中缀表示法,这意味着第二位实际上试图0用变量+count参数调用函数.
  • 你没有第二部分setq,这意味着你试图NIL隐含地设置上述部分.
  • 您实际上不需要设置任何内容以返回值

在这一点上,我们终于有一段代码将评估并正确运行(并且它不会引发您在上面提到的错误).

(defun count-numbers (list)
  (let ((count 0))
    (dolist (item list count)
      (cond ((null list) nil)
            ((numberp item) 
             (incf count)
             item))
      count)))
Run Code Online (Sandbox Code Playgroud)

dolist是一个迭代构造,为给定列表中的每个元素执行某些操作.这意味着您实际上不需要手动测试列表终止cond.此外,因为dolist没有收集结果,所以没有理由返回item它.您还会不必要地隐藏count您在声明的本地let.

(defun count-numbers (list)
  (let ((count 0))
    (dolist (item list)
      (when (numberp item) (incf count)))
    count))
Run Code Online (Sandbox Code Playgroud)

像往常一样,你可以通过更简单的loop电话完成所有这些工作.

(defun count-numbers (list)
  (loop for item in list
        when (numberp item) sum 1))
Run Code Online (Sandbox Code Playgroud)

这使计数器隐含,并使您无需手动返回它.事实上,除非这是一个编写自己的迭代函数的练习,否则Common Lisp有一个内置的count-if,它接受predicate sequence [some other options]并返回该匹配中count的项目.如果你想特别说出来,出于风格的原因,你可以这样做sequencepredicatecount-numbers

(defun count-numbers (list) (count-if #'numberp list))
Run Code Online (Sandbox Code Playgroud)

并完成它.


总之,试好,但请尽量读了语言的家庭为realzies问其他问题之前.