关于define-key(以及何时引用参数的问题)令人困惑的事情
题
使用define-key时似乎不应该引用KEYMAP。
(define-key org-remember-mode-map "\C-c\C-r" 'org-remember-kill)
我很困惑因为我认为未引用的函数的所有参数都会被评估,并且根据帮助,define-key是一个函数,而不是一个宏。我不明白为什么在调用define-key后可以修改KEYMAP的值。
(defun increment-value (a)
(setq a (+ 1 a)))
(setq my-num 10)
(increment-value my-num)
my-num ; ===> 10
更新:答案解释了一切,但对于那些仍然困惑的人,请让我用更多的例子来解决。
上面的增量值示例等同于:
(let ((n 0))
(print n) ; prints 0
(let ((a n))
(setq a (+ 1 a))
(print a) ; prints 1
)
(print n) ; prints 0
)
我认为,上面发生的事情与这个地图示例中发生的情况类似:
(let ((some-map '(1 2)))
(print some-map) ; prints (1 2)
(let ((a some-map))
(setq a (list 4 (second a)))
(print a) ; prints (4 2)
)
(print some-map) ; prints (1 2)
)
define-key中发生的事情类似于第二个some-map示例:
(let ((some-map '(1 2)))
(print some-map) ; prints (1 2)
(let ((a some-map))
(setcar a 4)
(print a) ; prints (4 2)
)
(print some-map) ; prints (4 2)
)
现在再次阅读这三个例子,你会得到它。另请阅读 http://www.emacswiki.org/emacs/ListModification
解决方案
您实际上并未更改'org-remember-map
(指向特定列表结构的指针),您正在修改实际结构。阅读此信息页,了解有关修改的详细信息列表。
具体来说,如果你看一下'make-keymap
的文档:
(make-keymap& optional string)
构造并返回一个新的键映射 表单(键映射CHARTABLE.ALIST)。 CHARTABLE是一个char表 所有字符的绑定 没有修饰语。其中的所有条目 最初是零,意思是“命令” 未定义&QUOT ;. ALIST是一个关联列表 它包含功能绑定 键,鼠标事件和任何其他 输入中出现的东西 流。最初,ALIST是零。
你会看到keymap是一个包含三个元素的列表。让我为你画一下(你可以 M-x艺术家模式):
org-remember-map
|
|
v
+----+----+ +----+----+
| | | --+--->+ / | \ |
+-+--+----+ +-/--+--\-+
| | |
v v v
keymap CHARTABLE ALIST
因此,'org-remember-map
的值类似于上面的结构,当你定义一个键时,你正在做的是改变 ALIST
blob结构的一部分。
其他提示
你的价值和名称价值映射令人困惑。
在增量值函数中,您不会将 a
的值更改为更改名称 a
到新值的映射。
从根本上说,没有办法改变10的值.10是10!
但在第一种情况下,您可以将名称 org-remember-mode-map
的映射修改为完全不同的映射(设置新值),也可以更改该名称指向的地图(其当前值)。这就是define-key的作用。
插图:
(setq a '(1 2)) -> (1 2)
(setcar a 4) -> 4
a -> (4 2)
你写的一切都是完全正确的。您缺少的是列表(键映射表示为列表)本身不是值,而是值的容器。因此,您可以将列表传递给函数并使该函数更改列表的值,但您拥有的列表仍然是相同的列表。
所有详细信息均在 Cons中elisp手册的单元格类型部分。