除了"符号"之外,为什么Clojure还有"关键字"?

Lau*_*ves 125 lisp scheme clojure keyword

我从其他方面了解其他Lisps(特别是Scheme).最近我一直在读关于Clojure的文章.我看到它有"符号"和"关键字".符号我很熟悉,但没有关键字.

其他Lisps有关键字吗?关键字如何与除了具有不同符号(即:冒号)之外的符号不同?

Bri*_*per 135

这是关键字和符号的Clojure文档.

关键字是评估自己的符号标识符.他们提供非常快速的平等测试......

符号是通常用于指代其他内容的标识符.它们可以在程序表单中用于引用函数参数,绑定,类名和全局变量......

关键字通常用作轻量级"常量字符串",例如用于散列映射的键或多方法的调度值.符号通常用于命名变量和函数,除了在宏等中之外,直接将它们作为对象进行操作并不常见.但是没有什么可以阻止你在使用关键字的地方使用符号(如果你不介意一直引用它们).

看出区别,最简单的方法是阅读Keyword.javaSymbol.java在Clojure的来源.有一些明显的实现差异.例如,Clojure中的符号可以包含元数据,而关键字则不能.

除了单冒号语法之外,您还可以使用双冒号来创建名称空间限定的关键字.

user> :foo
:foo
user> ::foo
:user/foo
Run Code Online (Sandbox Code Playgroud)

Common Lisp具有关键字,Ruby和其他语言也是如此.当然,它们在这些语言上略有不同.Common Lisp关键字和Clojure关键字之间存在一些差异:

  1. Clojure中的关键字不是符号.

    user> (symbol? :foo)  
    false
    
    Run Code Online (Sandbox Code Playgroud)
  2. 除非您特别限定它们,否则关键字不属于任何命名空间:

    user> (namespace :foo)
    nil
    user> (namespace ::foo)
    "user"
    
    Run Code Online (Sandbox Code Playgroud)

(感谢Rainer Joswig为我提供了要看的东西的想法.)

  • 关键字是轻量级的,并且具有方便的语法,我认为这就是它的全部内容.语言在没有它们的情况下可以正常工作但是它们很好用并且它们被广泛使用.你不能拥有他们的能力联盟,因为关键词总是自我评估(即你不能将它们用作变量或函数名),而且一般来说符号不能总是自我评估. (24认同)
  • 这解释了_what_差异,但不是为什么需要两种不同的结构.Clojure无法通过Keyword和Symbol的功能联合创造出一些东西吗? (10认同)
  • (相同?:qwe:qwe) - >是的.(相同?'qwe'qwe) - > false.符号使用内部字符串,因此比较也很快. (4认同)
  • 看来关键字作为哈希映射等中的键更有用,因为它们一旦评估就不会改变:`(eval (eval ':a))` vs `(eval (eval ''a))`。还有其他优点吗?就性能而言,它们是相同的吗? (2认同)

Rai*_*wig 29

Common Lisp有关键字符号.

关键字也是符号.

(symbolp ':foo) -> T
Run Code Online (Sandbox Code Playgroud)

什么使关键字特别:

  • :foo由Common Lisp reader解析为symbol关键字:: foo
  • 关键词评估自己:: foo - >:foo
  • 关键字符号的home包是KEYWORD包:keyword:foo - >:foo
  • 关键字从包KEYWORD导出
  • 关键字是常量,不允许分配不同的值

否则关键字是普通符号.因此,关键字可以命名函数或具有属性列表.

请记住:在Common Lisp中,符号属于一个包.这可以写成:

  • foo,当符号可在当前包中访问时
  • foo:bar,当从包BAR导出符号FOO时
  • foo :: bar,当符号FOO在包BAR中时

对于关键字符号,这意味着:foo,keyword:foo和keyword :: foo都是相同的符号.因此通常不使用后两种符号.

所以:foo被解析为在KEYWORD包中,假设在符号名称之前没有给出包名,默认情况下意味着KEYWORD包.


Gre*_*ill 6

关键字是评估自己的符号,因此您不必记住引用它们.

  • 关键字不是Clojure中的符号 (13认同)
  • 嗯,这不仅仅是角色,真的.关键字在评估后保留关键字,而符号则根据它们绑定的内容进行评估.它更像是语义差异,因为它们通常用于不同的目的. (10认同)
  • 是吗?打字:而不是"似乎不是一个大赢家,特别是因为:在大多数键盘上是一个额外的按键. (5认同)

Art*_*ldt 5

:keywords 也被许多集合特殊对待,允许使用一些非常方便的语法。

(:user-id (get-users-map))
Run Code Online (Sandbox Code Playgroud)

是相同的

((get-users-map) :user-id)
Run Code Online (Sandbox Code Playgroud)

这使事情变得更加灵活

  • 这对于符号也是如此,('a {'a 1 'b 2}) => 1 和 ({'a 1 'b 2} 'b) => 2。 (22认同)

Iva*_*rre 5

对于关键字,哈希值是在关键字首次构造时计算并缓存的。当查找关键字作为哈希键时,它只是返回预先计算的哈希值。对于字符串和符号,每次查找时都会重新计算哈希值。

为什么相同的命名关键字总是相同,它们包含自己的哈希值。由于地图和集合中的搜索是根据哈希键进行的,因此在大量搜索的情况下(而不是搜索本身)可以提高搜索效率。