5

当我像这样在 Common Lisp 中定义一个函数时:

(defun foo (n)
  (declare (type fixnum n))
  (+ n 42))

我预计一个电话(foo "a")会立即失败,但它却在调用+. declare表单不能保证静态类型检查吗?

4

2 回答 2

14

传统上,类型声明旨在用作对编译器进行优化的保证。对于类型检查,请使用check-type(但请注意,它也在运行时进行检查,而不是在编译时):

(defun foo (n)
  (check-type n fixnum)
  (+ n 42))

也就是说,不同的 Common Lisp 实现对类型声明的解释不同。例如,如果策略设置足够高,SBCL会将它们视为要检查的类型。safety

此外,如果您想要静态检查,SBCL 可能也是您最好的选择,因为它的类型推断引擎会警告您遇到的任何不一致。为此,ftype可以充分利用声明:

CL-USER(1): (declaim (ftype (function (string) string) bar))

CL-USER(2): (defun foo (n)
              (declare (type fixnum n))
              (bar n))
; in: DEFUN FOO
;     (BAR N)
; 
; caught WARNING:
;   Derived type of N is
;     (VALUES FIXNUM &OPTIONAL),
;   conflicting with its asserted type
;     STRING.
;   See also:
;     The SBCL Manual, Node "Handling of Types"
; 
; compilation unit finished
;   caught 1 WARNING condition

FOO
于 2012-03-01T18:24:24.073 回答
-1

声明只是对编译器的提示,因此它可以生成更高效的代码。换句话说,它不是静态检查。

于 2012-03-01T18:13:46.367 回答