1

举个例子,put在函数内部全局创建x属性及其值:

(defun foo ()
  (put 'spam 'x 1))

(foo)

(get 'spam 'x) ; -> 1

有没有办法在本地设置符号属性?

4

3 回答 3

3

不,因为'spam始终是相同的符号,所以不能在本地设置属性。

我不知道这是否适合您的情况,但您可以创建一个新符号并将属性放在上面。因为符号在函数之外不可用,属性也不可用。

(defun foo ()
  (let ((private (make-symbol "private")))
    (put private 'x 1)
    (get private 'x)))

(foo) ;=> 1

(get 'private 'x) ;=> nil

make-symbol返回一个“新分配的 [and] uninterned 符号”,这意味着返回的(make-symbol "private")符号与全局符号'private和所有其他符号不同。有关更多信息,请参见Emacs 手册中有关创建和实习符号的部分。

Emacs 还支持缓冲区局部变量,尽管这并不完全相同(符号的值对于特定缓冲区是局部的,但符号本身及其属性仍然是全局的)。

如果您只需要在本地将值绑定到名称,您还可以使用 Emacs 24 对词法绑定的支持,或者,如果您使用的是旧版本,则lexical-let可以使用cl包中的(包含在 Emacs 中)。

于 2013-11-11T00:52:01.460 回答
2

您可以在动态范围的意义上“本地”执行此操作:

(require 'cl-lib)
(defun foo ()
  (cl-letf (((get 'spam 'x) 1))
    (get 'spam 'x)))

(foo) ; -> 1

(get 'spam 'x) ; -> nil
于 2013-11-11T02:01:54.170 回答
0

虽然我不太明白你想要做什么,但在我看来你正在寻找一个闭包,即一个带有环境的函数。为此,您必须启用从 emacs 24.3 IIRC 开始支持的词法绑定。要启用它,请将缓冲区局部变量 lexical-binding 设置为 t。一个流行的闭包示例是加法器工厂,它是一个返回由常量相加的函数的函数。

(defun make-adder (constant)
  (lambda (y) (+ y constant)))

(make-adder 3)
;; As you can see a closure is a function with an environment associated
=> (closure ((constant . 3) t) (y) (+ y constant))

(funcall (make-adder 3) 2)
=> 5
(funcall (make-adder 5) 2)
=> 8

所以是的,使用闭包你可以为函数设置私有变量。

于 2013-11-12T23:18:23.957 回答