当我从LispWorks中的侦听器运行此函数时,它会使侦听器崩溃或提供异常和汇编语言数据。谁能告诉我它有什么问题?
(defun should-flip-block (rowlist)
(declare ((vector number) rowlist))
(if (= (length rowlist) 0) (eval nil)
(let* ((exithigh (= (car (last rowlist)) 2))
(enterhigh (= (first rowlist) 2)))
(and exithigh enterhigh))))
它被称为(should-flip-block '(1 2 1 2 1))
。
答案 0 :(得分:3)
有问题的声明
请注意,并非所有Common Lisp实现都会认为(declare ((vector number)) rowvector)
是有效的声明。
改为(declare (type (vector number) rowvector))
。
错误:列表不是矢量
您看到的问题是因为您对实施做出了谎言而safety
设置得很低。你告诉Lisp这个参数是一个向量,但是你传递一个列表(它不是一个向量)。
然后该函数使用对FIRST
和LAST
的调用,这些调用不适用于向量,而是列表。
运行safety
值更高的代码
默认情况下,不要以低安全性运行Common Lisp。使用默认安全值2或3。
使用LispWorks 6.1.1:
CL-USER 43 > (proclaim '(optimize (safety 2)))
NIL
现在我重新编译该函数,然后调用它:
CL-USER 44 > (should-flip-block '(1 2 1 2 1))
Error: Variable ROWLIST was declared type (VECTOR NUMBER) but is being
bound to value (1 2 1 2 1)
1 (abort) Return to level 0.
2 Return to top loop level 0.
现在您看到了有用的错误,而不是段违规。
文字向量
#(1 2 1 2 1)
是一个向量。
注意:LIST
类型没有参数
请注意,Common Lisp中不存在类型(list number)
,无法定义。类型list
不能包含参数。根据类型cons
定义这样的类型也是不可能的 - 递归类型不起作用。
答案 1 :(得分:2)
declare
rowlist
vector
list
last
使用first
和vector
对list
进行处理。eval
这意味着编译器假设您传递给它的对象是nil
,因此,当您传递let*
时,您会得到未定义的行为
了解Lisp中声明的最重要的事情是:做不撒谎到编译器。 即,如果你违反了你的声明(就像你刚才那样),你就会被烧毁。
(此外,您不需要{{1}} {{1}},并且不需要{{1}},因为您使用的是仅绑定一次的变量。