Functional programming 始终获取“返回源:当前没有名为NIL的块可见”

Functional programming 始终获取“返回源:当前没有名为NIL的块可见”,functional-programming,lisp,common-lisp,Functional Programming,Lisp,Common Lisp,这给了我一个错误返回:没有名为NIL的块当前可见。我试着把return语句四处移动,但我不确定它是什么意思 请以Lisp方式缩进代码,这可以在许多编辑器中自动完成,如Emacs: (defun take-n (lst i) (setf newlst '()) (dotimes (n i) (setf newlst (cons (car lst) newlst)) (print (cons (car lst) newlst)) (setf lst (cdr

这给了我一个错误返回:没有名为NIL的块当前可见。我试着把return语句四处移动,但我不确定它是什么意思

请以Lisp方式缩进代码,这可以在许多编辑器中自动完成,如Emacs:

(defun take-n (lst i)
  (setf newlst '())    
  (dotimes (n i)
    (setf newlst (cons (car lst) newlst))
    (print (cons (car lst) newlst))
    (setf lst (cdr lst)))
  (return newlst))
(print (take-n '(1 2 3) 2))
不要设置一个事先没有声明的变量:这里的setf newlst'指的是一个假设的全局变量newlst,但在函数中,您应该尽量只使用局部状态。使用let在块中引入变量,如下所示:

(defun take-n (lst i)
  (setf newlst '())
  (dotimes (n i)
    (setf newlst (cons (car lst) newlst))
    (print (cons (car lst) newlst))
    (setf lst (cdr lst)))
  (return newlst))

(print (take-n '(1 2 3) 2))
setf newlst cons car lst newlst也可以写成push car lst newlst,但请不要使用过度缩写的名称;例如,您可以使用列表和新列表

return返回名为nil的封闭块,但这里没有这样的块。相反,defun引入了一个名为的隐式块,与您定义的函数类似,即隐式:

(let ((new-list ()))
  ...
  ;; here you can setf new-list if you need
  ...)
所以,如果您想从它返回,您需要从take-n newlst返回

但是,您不需要返回,因为函数中计算的最后一个表单无论如何都是与函数调用关联的值

请以Lisp方式缩进代码,这可以在许多编辑器中自动完成,如Emacs:

(defun take-n (lst i)
  (setf newlst '())    
  (dotimes (n i)
    (setf newlst (cons (car lst) newlst))
    (print (cons (car lst) newlst))
    (setf lst (cdr lst)))
  (return newlst))
(print (take-n '(1 2 3) 2))
不要设置一个事先没有声明的变量:这里的setf newlst'指的是一个假设的全局变量newlst,但在函数中,您应该尽量只使用局部状态。使用let在块中引入变量,如下所示:

(defun take-n (lst i)
  (setf newlst '())
  (dotimes (n i)
    (setf newlst (cons (car lst) newlst))
    (print (cons (car lst) newlst))
    (setf lst (cdr lst)))
  (return newlst))

(print (take-n '(1 2 3) 2))
setf newlst cons car lst newlst也可以写成push car lst newlst,但请不要使用过度缩写的名称;例如,您可以使用列表和新列表

return返回名为nil的封闭块,但这里没有这样的块。相反,defun引入了一个名为的隐式块,与您定义的函数类似,即隐式:

(let ((new-list ()))
  ...
  ;; here you can setf new-list if you need
  ...)
所以,如果您想从它返回,您需要从take-n newlst返回

但是,您不需要返回,因为函数中计算的最后一个表单无论如何都是与函数调用关联的值

您不需要使用RETURN。在Lisp中,函数体中的最后一个表达式将自动返回,因此只需将变量放在函数的末尾即可。此外,您应该使用LET绑定局部变量,而不是分配全局变量

(block take-n
  ...)
您得到的错误是因为DEFUN在函数体周围放置了一个命名块,因此需要使用return-from-take-n newlst。return只能用于从未命名块返回名称为NIL的块;它们会像DO一样自动循环放置宏。

您不需要使用RETURN。在Lisp中,函数体中的最后一个表达式将自动返回,因此只需将变量放在函数的末尾即可。此外,您应该使用LET绑定局部变量,而不是分配全局变量

(block take-n
  ...)
您得到的错误是因为DEFUN在函数体周围放置了一个命名块,因此需要使用return-from-take-n newlst。return只能用于从未命名块返回名称为NIL的块;它们会像DO一样自动围绕循环宏放置。

还有dotimes n i newlst也dotimes n i newlst记住setf lst cdr lst实际修改原始列表记住setf lst cdr lst实际修改原始列表