在这篇文章中 EB 是这样说的
'{"oranges": 2, "apples": 6, "pears": 5}'
是 JSON 中的无序集合,而这个 s 表达式
'((ORANGES 2) (APPLES 6) (PEARS 5))
是一个嵌套列表,但显然不是一个无序集合。他说
是的,这个 [Lisp s 表达式] 标点符号更少,这很好。然而,现在假设我 希望我的数据不仅仅是一个嵌套列表,而是一个映射 水果名称到数字。我也希望它是一个有效的映射。 换句话说,我想要 JSON
'{"oranges": 2, "apples": 6, "pears": 5}'
他继续区分有序集合和无序集合。 JSON 怎样使它成为无序集合,或者如他所说,是水果和数字之间的映射?为什么,怎么少了s-表达式?然后文章中有这个讨论,我也没有很好地理解。
此外,EB 使用此
#S(HASH-TABLE :TEST FASTHASH-EQL (ORANGES . 2) (APPLES . 6) (PEARS . 5))
当我,一个初学者,只见过这种 hash 的东西时(emacs lisp 例子):
(setq hash-of-countries (make-hash-table :test 'equal))
(puthash "Mexico" "MX" hash-of-countries)
(puthash "United States" "USA" hash-of-countries)
这个
#S(HASH-TABLE...
是什么意思?总的来说,为什么他不喜欢 s 表达式而不是 JSON?任何清理工作将不胜感激。
JSON 只是数据结构的文本表示,使用 Javascript 启发的表示法。 根据定义,JSON 对象是键/值对的无序集合。
{"oranges": 2, "apples": 6, "pears": 5}
相当于 {"oranges": 2, "pears": 5, "apples": 6}
。写出的对象如何映射到给定语言的内部数据结构取决于特定的 JSON 解析器和语言的约定。在 Common Lisp land 中,有一些库将 JSON 对象表示为哈希表、关联列表、属性列表、CLOS 对象、结构等。只要它是某种类型的键值映射,从根本上来说什么并不重要。
'((ORANGES 2) (APPLES 6) (PEARS 5))
是一个关联列表(简称alist),尽管它更常见地使用点对来编写:'((ORANGES . 2) (APPLES . 6) (PEARS . 5))
。这是 Common Lisp 中一组键值对的非常常见的约定 - 甚至有处理此类列表的标准函数。在处理少量键时,它们甚至可能比哈希表更有效。你经常会看到它们,因为 CL 没有文字哈希表的标准语法(与 Racket 和 Clojure 等其他一些 Lisp 家族语言不同)。仅当列表中存在相同键的重复项时,顺序才重要 - 每个键都有一个实例并不是像哈希表那样强制执行的,这只是一种约定。
#S(HASH-TABLE :TEST FASTHASH-EQL (ORANGES . 2) (APPLES . 6) (PEARS . 5))
只是该文章的作者提出的一些伪代码,作为“如果”它确实有文字哈希表。它似乎基于“读取文字结构的语法”,但并不完全相同。 (也许有一些实现支持它作为扩展?)
作者对 JSON 的偏好超过了相同数据结构的 S 表达式表示,这只是个人偏好。对于在服务之间交换数据,尤其是通过 Web API,JSON 是事实上的标准,但程序如何表示它以供自己使用(例如在配置或数据文件中)更多的是基于意见,因此不是 Stack Overflow 的主题。