【问题标题】:How to exit a loop in lisp once the function is performed?函数执行后如何退出 lisp 中的循环?
【发布时间】:2015-01-13 17:05:28
【问题描述】:

我是 LISP 的初学者,希望你能为我解决我的困惑。我的代码如下:

(defun retrieve (element closed)
            (if (= (length closed) 0)
             (setf closedlist '(a))
              (dolist (count closed)
              (when (equal element (car count))
               (progn (check (childvalue (symbol-value count)) count) 
               (return)));;;endif
              );;;endouterloop
            )
           )

这是第一个函数,它将接收一个名为“元素”的对象和一个名为“关闭”的列表。下一个函数如下:

(defun check (child close)
           (setf tempvalue child)
           (dotimes (count (length tempvalue));;;1st loop
             (setf front (car tempvalue))
             (setf templist close)
             (dotimes (count1 (length close));;;2nd loop
               (if (= (length close) 1) 
                (if (string= front (car templist)) 
                    ((remove (nth count) child) (return));;;true
                    (setf templist (car templist));;;else
                 )
                 (if (string= front (car templist)) 
                    (setf child (remove (nth count child) child))
                    (setf templist (cdr templist));;;else
                   )
                 )
               );;;2nd loop
             (setf tempvalue (cdr tempvalue))
             );;;1stloop
           (format t "child ~S~%" child)
           )

我的问题是,从第一个函数开始,当我在第一个函数中并且满足条件时,我将调用第二个函数(检查)。但是,在我从第一个函数(检索)调用第二个函数(检查)并成功执行操作后,我想从第一个函数退出 dotimes 循环,但我做不到。

如果我尝试向它添加(返回),程序将退出循环,而不会在语句中执行其他操作。在这种情况下,(check (childvalue (symbol-value temp)) (nth count closed))。

有人可以就调用辅助函数后如何退出循环提供任何建议吗?谢谢。

【问题讨论】:

  • 这是非常糟糕的代码:未格式化的代码、大量未声明的变量、通过循环中的 NTH 访问列表元素、函数 CHECK 中的几个错误、重复计算列表的长度......你应该扔掉代码并重新开始。使用 Lisp 编译器——它会给你很多错误和警告。
  • @RainerJoswig 对不起,我在这方面很初学者。你介意给我一个关于“未声明变量”的例子吗?除了通过循环中的 NTH 之外,还有没有更好的方法来访问列表元素?
  • @Piiinkyy 现在不用担心,你会学会的。不过,您现在有点在 lisp 的语法中键入 C 风格..
  • @RainerJoswig Piiinkyy 显然是 stackoverflow 上的新手和 lisp 中的新手,对于双初学者来说,他发布了非常清晰、格式正确且完全有效的问题。你必须给他一些信任!
  • 这是一本免费下载的书,它以一种很好的方式解释了基本的 Lisp:cs.cmu.edu/~dst/LispBook

标签: function lisp common-lisp


【解决方案1】:

if 的格式为 (if <condition> <if-true> <if-false>)

您写了(if <condition> (check ...) (break) ),所以break 处于<if-false> 的位置,并且在条件为假时第一次熄灭。要将多个语句组合为一个,请使用progn

(if (equal element temp)
    (progn (check (childvalue (symbol-value temp)) (nth count closed)) 
           (return)))

Progn 除了将语句组合在一起并返回最后一个语句的结果之外,什么都不做。

您也可以使用when 代替ifWhen(when <condition> <if-true>... ) 一样工作。它可以有多个 if-true 但没有 if-false。我认为这非常适合您的情况。

为了完整起见,when 的反义词是 unless。它有多个 if-false 并且没有 if-true。 (unless cond ...) 等价于(when (not cond) ...)

旁注:作为旁注,将右括号放在同一行,不要将) 放在不同的行上。您的编辑器应该为您缩进内容,然后只需通过缩进查看和导航自己,然后忘记那些结束括号。一旦你开始这样做,代码看起来会比许多传统语言更清晰。

第二面注意: 如果你想要局部变量,请使用let,否则你会在某些实现中得到未声明的变量通知。示例:

(defun check (child close)
  (let ((tempvalue child)
        (front)
        (templist))
    (dotimes (count (length tempvalue))
      (setf front (car tempvalue))
      (setf templist close)
      (dotimes (count1 (length close))
        (if (= (length close) 1) 
            (if (string= front (car templist)) 
                ((remove (nth count) child) (return))
                (setf templist (car templist)))
            (if (string= front (car templist)) 
                (setf child (remove (nth count child) child))
                (setf templist (cdr templist)))))
      (setf tempvalue (cdr tempvalue)))
    (format t "child ~S~%" child)))

【讨论】:

  • @RainerJoswig 啊我现在明白你的意思了,我错过了。我会重写它。
  • 好吧,我就不重写了,我想不通它应该做什么
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-13
  • 1970-01-01
  • 1970-01-01
  • 2018-03-28
相关资源
最近更新 更多