Emacs Lisp:#s不会每次都创建一个新的哈希表 [英] Emacs Lisp: #s does not create a new hash table each time

查看:63
本文介绍了Emacs Lisp:#s不会每次都创建一个新的哈希表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下功能:

(defun inc-map ()
  (let ((ht #s(hash-table test contents-hash))) 
    (dolist (i (list 1 2 3 4))
      (let ((old-val (or (gethash "foo" ht)
             0)))
    (puthash "foo" (+ 1 old-val) ht)))
    ht))

尽管这个函数似乎在本地定义了 ht 符号,但是这个函数似乎并不是透明的。特别地,调用它返回哈希表foo - > 4 ,再次打电话给foo - > 8 ,第三次返回foo - > 12 等等。

Despite the fact that this function seems to define the ht symbol locally, the function doesn't seem to be referentially transparent. In particular, calling it once returns the hash table "foo" -> 4, calling it a second time returns "foo" -> 8, a third time returns "foo" -> 12 and so on.

这里究竟发生了什么,如何更改此功能以便透明(并返回foo - > 4 每次)?

What exactly is going on here and how do I change this function to be referentially transparent (and return "foo" -> 4 every time)?

推荐答案

一个(轻微的)文档错误,因为它暗示了使用打印的表示创建一个新的哈希表 - 一个可以被误解的语句。

This might be considered a (slight) documentation bug, in that it suggests a little too firmly that using the printed representation creates a new hash table -- a statement which is open to misinterpretation.

但是,您会注意到,文档说,它是识别散列表的打印表示的elisp 。

However, you'll note that the documentation says that it's the elisp reader that recognises the printed representation of a hash table.

因此,使用 #s 与调用 make-hash-table 不同。这里的区别相当于引用列表'(1 2 3)和调用(列表1 2 3)

Therefore using #s is not the same as calling make-hash-table. The difference here is equivalent to the difference between quoting a list '(1 2 3) and calling (list 1 2 3).

在每种情况下,前者由读者处理,因此相同的单个结果对象(分别为哈希表或列表)在每个评估中都会看到。

The former in each case is processed by the reader and hence the same, single resulting object (hash table or list respectively) is seen during each evaluation.

相反,在后一种情况下,读者正在生成代码,当被评估时,将创建一个新的哈希表或列表;因此您在每次评估期间都会看到一个新对象。

Conversely, in the latter instances the reader is generating code which, when evaluated, will create a new hash table or list; and therefore you see a new object during each evaluation.

这篇关于Emacs Lisp:#s不会每次都创建一个新的哈希表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆