服务器下面的代码显示列表中的整数.
(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))
我对它的运行感到惊讶,因为你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问其他问题之前.