关于定义键的一些令人困惑的事情(以及何时引用参数的问题)
使用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
)
我认为上面发生的情况与此 some-map 示例中发生的情况类似:
(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
It seems one is not supposed to quote KEYMAP when using define-key.
(define-key org-remember-mode-map "\C-c\C-r" 'org-remember-kill)
I'm confused because I think that all arguments of a function that is not quoted are evaluated, and according to the help, define-key is a function, not a macro. I don't see why the value of KEYMAP can be modified after a call of define-key.
(defun increment-value (a)
(setq a (+ 1 a)))
(setq my-num 10)
(increment-value my-num)
my-num ; ===> 10
Update: The answers explain everything, but for those still confused, let me clear up with more examples.
My increment-value example above is equivalent to this:
(let ((n 0))
(print n) ; prints 0
(let ((a n))
(setq a (+ 1 a))
(print a) ; prints 1
)
(print n) ; prints 0
)
What's going on above is, I think, similar to what's going on in this some-map example:
(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)
)
What's going on in define-key is similar to this second some-map example:
(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)
)
Now read the answers again with these three examples in mind and you will get it. Read also http://www.emacswiki.org/emacs/ListModification
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您实际上并没有改变
'org-remember-map
是什么(指向特定列表结构的指针),您正在修改实际的结构。有关修改的详细信息,请阅读此信息页面列表。具体来说,如果您查看
'make-keymap
的文档:您将看到键盘映射是一个包含三个元素的列表。让我为你画一下(是的Mx艺术家模式):
所以,
'org-remember-map
类似于上面的结构,当您定义一个键时,您所做的就是更改ALIST
blob 部分中指向的内容结构。You aren't actually changing what
'org-remember-map
is (a pointer to a particular list structure), you are modifying the actual structure. Read this info page for details on modifying lists.Specificially, if you take a look at the documentation for
'make-keymap
:You'll see that keymap is a list with three elements. Let me draw that for you (yay M-x artist-mode):
So, the value of the
'org-remember-map
is something like the above structure, and when you define a key, what you are doing is changing what is pointed to in theALIST
blob part of the structure.您混淆了值和名称-值映射。
在增量值函数中,您不会更改
a
的值,而是更改名称a
到新值的映射。从根本上来说,没有办法改变 10 的值。10 就是 10!
但在第一种情况下,您可以将名称
org-remember-mode-map
的映射修改为完全不同的映射(设置新值),或者您可以更改 该名称指向的地图(其当前值)。这就是define-key 的作用。插图:
you're confusing value and name-value mapping.
in your increment-value function, you're not changing
a
's value as much as changing the mapping of the namea
to a new value.Fundamentally, there is no way to change the value of 10. 10 is 10!
But in the first case, you can either modify the mapping of the name
org-remember-mode-map
to a fully different map (set a new value), or you can alter the map pointed by that name (its current value). This is what define-key does.Illustration:
你写的一切都是完全正确的。您缺少的是列表(键盘映射表示为列表)本身不是值,而是值的容器。因此,您可以将列表传递给函数并让该函数更改列表的值,但您拥有的列表仍然是相同的列表。
所有详细信息都在Cons Cell Type< elisp 手册的 /a> 部分。
Everything you write is completely correct. The thing you are missing is that lists (keymaps are represented as lists) are not values themselves, but containers of values. Thus, you can pass a list to a function and have that function change the values of the list, but the list you have is still the same list.
All the details are in the Cons Cell Type section of the elisp manual.