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

如何将参数传递到Elisp中的函数中? 来自C++背景,我试图找出Elisp中如何传入参数。虽然我承认,也许措辞可能不同,但我想知道它是否更接近C++通过引用或通过值传递的想法?如果我改变方法本身中的参数,它会改变函数调用中传入的参数吗?,lisp,parameter-passing,elisp,Lisp,Parameter Passing,Elisp,所有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

所有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。Cf.-引用的参数也会被评估:评估将删除引用


PS2。Cf.-它接受符号变量名并修改其值。这只适用于全局动态变量,不适用于词汇变量。这不是一个好主意。

实际上,在Emacs Lisp中,没有像通过值或引用传递参数这样的事情,更不用说指针了。但传递给函数的所有参数都将提前求值,只有那些带有“前缀”的参数除外。请始终记住,在设置变量时,始终只需创建带有值的符号

因此,如果要修改函数中某个变量的值,只需修改该函数中该变量符号的值即可

检查我下面的代码

(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
注意!如果变量是词汇绑定的变量,那么仍然可以修改符号的值,但不能修改词汇环境中的值

代码如下:

(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

始终计算所有函数参数。”不是前缀,而是缩写为的reader宏,其计算结果为其第二个术语。是的,我知道它是引号形式,但也类似于该变量的前缀。无论如何,你没有抓住重点。您是否查看了我上面的代码片段,这正是我试图指出的。@请注意,如果变量具有词法作用域(此处不是这种情况),则传递变量的符号不允许您使用set修改变量的值,因为词法值和符号的值不是同一事物。