You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Emacs 27.1回调报(void-variable buffer)错误,Elisp不支持闭包吗?

问题解答

Emacs Lisp 完全支持闭包特性,你遇到的(void-variable buffer)错误和闭包本身无关,核心原因是没有启用词法绑定(lexical binding)——Elisp默认使用动态绑定,只有开启词法绑定后,lambda才能正确捕获外部变量形成闭包。

错误原因分析

Emacs 24及以上版本就已经支持闭包,但默认的动态绑定模式下,函数内的变量会在调用时动态查找,而不是被lambda捕获保存。你的make-callback函数里,buffer参数在动态绑定环境下不会被闭包保留,当url-retrieve异步调用回调时,buffer变量已经不存在,就会触发未定义变量的错误。

解决方法

只需要开启词法绑定即可,有两种方式:

  • 如果是在文件中编写代码,在文件最顶部添加一行声明:
    ;; -*- lexical-binding: t -*-
    
  • 如果是在scratch缓冲区测试,先执行以下代码开启词法绑定,再重新定义你的函数:
    (setq lexical-binding t)
    

修改后的完整代码示例

;; -*- lexical-binding: t -*-

(defun make-callback (buffer)
  (lambda (status)
    (message "buffer: %s" buffer)))

(defun make-rest-call ()
  (interactive)
  (let* ((buffer (current-buffer))
         (callback (make-callback buffer))
         (url "some-url")
         (url-request-method "POST")
         (url-request-extra-headers 
           `(("Content-Type" . "application/json")))
         (url-request-data (json-encode '((key . "value"))))) ; 补全示例数据
    (url-retrieve url callback)))

开启词法绑定后,make-callback返回的lambda会捕获传入的buffer变量,异步回调执行时就能正确访问到这个变量,不会再出现未定义的错误。

内容的提问来源于stack exchange,提问作者chris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 05:27:15