【问题标题】:Why won't the Common LISP Return function work?为什么 Common LISP Return 函数不起作用?
【发布时间】:2021-02-11 08:27:42
【问题描述】:

我已经在 common lisp 中工作了一段时间,但我不明白为什么我使用的循环不会返回列表。如果我在循环结束时使用“Finally”语句,它将打印新列表(正确!),但它不会在它之外打印或让我将它用于任何事情。

我发现的所有示例都表明 return 语句应该这样做,但当我尝试这样做时仍然没有骰子。它只是告诉我,当我尝试在循环之外使用它时,meanList 是未定义的,并且在那里初始化它也不起作用。

循环的最终目标是返回每组数据元素的平均值列表。

    (defparameter data
                     ' ((2.0 8.0) (0.9 1.2) (6.0 2.0)
                       (7.0 3.5) (4.0 6.0) (1.0 4.0)))

    (loop for i in data
      do (setq j (mean i)) collect j into meansList
      finally (return (meansList))

mean 函数返回列表的平均值。我已经检查了好几次,都按预期工作,但如有必要,我可以在这里提供。

【问题讨论】:

  • 这属于“由拼写错误引起的”问题;要评估的变量周围的多余括号,将其转换为函数调用。

标签: loops lisp common-lisp collect


【解决方案1】:

(meansList) 表示应用不带参数的函数meansList。由于 Common Lisp 是一个 Lisp2,你会得到一个错误,即函数 meansList 不存在。如果您知道 C 类型语言,那么您会这样做:

int c = 10;
return c();  // is this the variable that turns into 10? 

您还应该考虑将*earmuffs* 用于您的全局变量,因为它们是动态的。如果您曾经有一个名为 data 的参数调用了一个依赖于全局 data 的函数,那么它将被临时更改,即使在中等项目中,这就像大海捞针一样。

另请注意,loop 创建了一个名为 nil 的块,而 return 使用了最近的名为 nil 的块,因此您从 loop 返回。例如。它成为循环的评估。要从使用循环的函数返回,您需要使用(return-from function-name whatever-expression-to-compute-value)

我还看到j 的突变是不必要的。可以这样写:

(loop :for i :in *data*
      :collect (mean i) :into meansList
      :finally (return meansList))

如果你 collect 任何东西,但没有提及它也会返回它,所以这是一样的:

(loop :for i :in *data*
      :collect (mean i))

Practical Common Lisp 中的第 Loop for black belts 章有很好的示例,The Loop macro in CL Cookbook

【讨论】:

  • (loop for i in data collect (mean i) into meansList) 像这样?这似乎也不起作用。当我尝试打印它时,它仍然告诉我 meanList 的值不存在。还有,如果不告诉它归还到哪里,以后怎么用?
  • @kra361 meansList 只能从循环内访问。它是表单的结果,它是两种表单中收集的值的列表。你可以(print (loop ...))或者(let ((ml (loop ...))) (print ml))
  • @kra361 作为补充:此代码可以只是(mapcar #'mean *data*)
  • 我想我只是误解了循环输出在这种情况下是如何工作的。在查看了 mapcar 位后,它与我想要的更接近了。
猜你喜欢
  • 2021-10-04
  • 2019-01-18
  • 1970-01-01
  • 1970-01-01
  • 2011-11-14
  • 2017-10-19
  • 2015-07-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多