首页 > 解决方案 > 为什么 SBCL(或一般的 Common lisp?)不喜欢我的循环?

问题描述

递归 find-dir-upwards 按预期工作,但 find-dir-upwards-loop 拒绝编译,抱怨 SBCL(Win64、Portacle 1.4、SBCL 2.0.0)下的类型不匹配(即使添加了类型注释)。

我做错了什么 ?

(defun find-dir-upwards-loop (dir marker-file)
  (loop for prev = nil then curr
        for curr = dir then (uiop:pathname-parent-directory-pathname curr)
        until (equal curr prev)
        with f = (merge-pathnames marker-file curr)
        when (uiop:file-exists-p f) return curr))

(defun find-dir-upwards (dir marker-file)
  (let ((f (merge-pathnames marker-file dir)))
    (if (uiop:file-exists-p f)
        dir
        (let ((parent (uiop:pathname-parent-directory-pathname dir)))
          (unless (equal dir parent)
            (find-dir-upwards parent marker-file))))))

标签: common-lisp

解决方案


FOR部分答案之后的WITH :

(loop for x = 0 then (+ x 1)
      with y = (+  x 1)
      when (> x 10) return (list x y))

这是一系列事件:

  1. X变量将被建立
  2. Y变量将被建立并初始化为(+ x 1)
  3. X变量将设置为0
  4. ...

如您所见,在操作 1) X中将是一个变量,但它不会被初始化为0. 这将发生在操作 3)中。因此在操作 2) X中不会被初始化为0 -> 它的值可能是NIL. 添加1NIL是一个错误。


推荐阅读