简体   繁体   English

在elisp中,如何将函数放入变量中?

[英]In elisp, how do I put a function in a variable?

I want to allow the user to choose their own command in the "customize" emacs backend (and generally be able to store an executable form name in a variable) but this does not work : 我想允许用户在“自定义”emacs后端中选择自己的命令(并且通常能够将可执行的表单名称存储在变量中)但这不起作用:

    (defun dumb-f ()
    (message "I'm a function"))

    (defvar my-function "dumb-f")

    (my-function)
    ==> Debugger entered--Lisp error: (invalid-function "dumb-f")

    (setq my-function 'dumb-f)

    (my-function)
    ==> Debugger entered--Lisp error: (invalid-function "dumb-f")

I tried various forms, but still no luck, and I'm having a hard time searching for it, I get kilopages of results about functions and variables, but none about how to put the former in the latter..? 我尝试了各种各样的形式,但仍然没有运气,而且我很难找到它,我得到了关于函数和变量的结果,但没有关于如何将前者放入后者......?

Note that in Emacs Lisp, symbols have a value cell and a function cell, which are distinct. 请注意,在Emacs Lisp中,符号具有值单元格和功能单元格,它们是不同的。 When you evaluate a symbol, you get its value . 评估符号时,您将获得其 When you evaluate a list beginning with that symbol, you call its function . 当您评估以该符号开头的列表时,可以调用其函数 This is why you can have a variable and a function with the same name. 这就是为什么你可以有一个变量和一个具有相同名称的函数。

Most kinds of assignment will set the value (eg let , setq , defvar , defcustom , etc...) -- and as ryuslash shows you can assign a function as a value and call it via funcall -- but there are also ways to assign to a symbol's function cell directly using fset (or flet , defalias , etc) 大多数类型的赋值都会设置值(例如letsetqdefvardefcustom等等) - 并且正如ryuslash所示,您可以将函数指定为值并通过funcall调用它 - 但是也有方法可以使用fset (或fletdefalias等)直接分配给符号的函数单元格

(fset 'my-function 'dumb-f)
(my-function)

In your case I would use ryuslash's answer (except you need to use defcustom rather than defvar if you want it to be available via customize ). 在你的情况下,我会使用ryuslash的答案(除非你需要使用defcustom而不是defvar如果你想通过customize提供它)。

Also, regarding "I'm having a hard time googling for it"; 此外,关于“我很难用Google搜索”; always remember that Emacs is self-documenting , and among other things contains a good manual complete with index (well, more than one manual, in fact). 永远记住,Emacs是自我记录的 ,除了其他东西之外还包含一个完整的索引(好吧,实际上不止一本手册)。 So even if Google remains your first port of call, it shouldn't also be your last if you can't find what you're looking for. 因此,即使Google仍然是您的第一个停靠点,如果您找不到所需内容,也不应该是最后一个。 From the contents page of the elisp manual you can navigate to "Functions" and then "Calling functions" and you will be told about funcall almost immediately. 从elisp手册的内容页面,您可以导航到“功能”,然后导航到“调用功能”,您将立即被告知funcall

To run a function stored in a variable you can use funcall 要运行存储在变量中的函数,可以使用funcall

(defun dumb-f ()
  (message "I'm a function"))

(defvar my-function 'dumb-f)

(funcall my-function)
==> "I'm a function"

@phils' great answer mentions various ways of setting a symbol's function definition, but I also needed a way of getting it. @phils的好回答提到了设置符号函数定义的各种方法,但我还需要一种方法来获取它。

To get a symbol's value as a function you can use the function symbol-function . 要将符号的值作为函数获取,可以使用函数symbol-function

For example: 例如:

; remember the old value of 'foo as a function
(set 'foo-backup (symbol-function 'foo))
; change it, to experiment or whatever
(defun foo () whatever)
; revert it back to what it was
(fset 'foo foo-backup)

And indeed the emacs manual was helpful here, in particular: 事实上,emacs手册在这里很有帮助,特别是:

https://www.gnu.org/software/emacs/manual/html_node/elisp/Symbol-Components.html https://www.gnu.org/software/emacs/manual/html_node/elisp/Symbol-Components.html

https://www.gnu.org/software/emacs/manual/html_node/elisp/Function-Cells.html https://www.gnu.org/software/emacs/manual/html_node/elisp/Function-Cells.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM