如何将参数传递给Elisp中的函数?

时间:2018-01-21 04:51:38

标签: lisp parameter-passing elisp

来自C ++背景,我试图弄清楚如何将参数传递给Elisp中的方法。虽然我承认也许措辞可能有所不同,但我想知道它是否更接近C ++通过引用传递或通过值传递的想法?如果我改变方法本身的参数,它会改变函数调用中传入的参数吗?

2 个答案:

答案 0 :(得分:6)

所有Lisps(Emacs LispCommon Lisp)始终按值传递参数:

(defparameter x 42)  ; defconst in Emacs Lisp
(defun test (x)
  (setq x 10))
(test x)
==> 10
x
==> 42

但请注意,某些值实际上是指针(或者更确切地说,是带有组件的对象),因此函数可以通过副作用修改其内容

(defparameter x (list 1 2))
(defun test (x)
  (setf (first x) 42
        (second x) 24
        x 17))
(test x)
==> 17
x
==> (42 24)

<强> PS1 即可。参看When to use ' (or quote) in Lisp? - “引用的参数”也被评估:评估剥离引用。

<强> PS2 即可。参看add-to-list - 它接受符号(变量名称)并修改其值。这仅适用于全局动态变量,不适用于词汇变量。不是一个好主意。

答案 1 :(得分:0)

实际上,在Emacs Lisp中,没有像通过值或引用传递参数(更不用说指针)这样的事情。但是传递给函数的所有参数将被预先评估,除非前缀为'。永远记住,设置变量时,总是只创建带有值的符号。[1]

因此,如果要修改函数中变量的值,只需要做的就是修改该函数中该变量符号的值。

检查下面的代码。

(defvar my-val 1)

(defun my-func-value (val)
  (setq val 2))

(defun my-func-symbol (sym)
  ;; NOTE! using set instead of setq,
  ;; casue we want symbol "my-val" be evaluated from "sym" here
  (set sym 2))

(my-func-value my-val) ; evaluate my-val before passed into function
(message "my-val: %s" my-val) ; my-val: 1

(my-func-symbol 'my-val) ; pass my-val symbol directly into function
(message "my-val: %s" my-val) ; my-val: 2

注意!如果变量是一个词法绑定变量[2],那么您可以修改符号的值,但不能修改词法环境中的值,这仍然是正确的。

代码如下:

(let ((my-lexical-var 1))
  (my-func-symbol 'my-lexical-var)
  ;; evaluate from lexical environment
  (message "my-lexical-var: %s" my-lexical-var) ; my-lexical-var: 1
  ;; evaluate from the symbol
  (message "symbol my-lexical-var: %s" (symbol-value 'my-lexical-var))
  ; symbol my-lexical-var: 2