【问题标题】:Common Lisp type declarations not working as expectedCommon Lisp 类型声明未按预期工作
【发布时间】:2012-03-01 18:11:46
【问题描述】:

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

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

我预计像 (foo "a") 这样的调用会立即失败,但在调用 + 时却失败了。 declare 表单不保证静态类型检查吗?

【问题讨论】:

    标签: lisp common-lisp static-typing


    【解决方案1】:

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

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

    也就是说,不同的 Common Lisp 实现对类型声明的解释不同。 SBCL,例如,will treat them as types to be checked,如果 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
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-26
        • 1970-01-01
        • 1970-01-01
        • 2023-03-28
        相关资源
        最近更新 更多