Clojure,为什么键和值都使用":"?

  • 本文关键字:键和值 Clojure clojure
  • 更新时间 :
  • 英文 :

(defn explain-defcon-level [exercise-term]
  (case exercise-term
        :fade-out          :you-and-what-army
        :double-take       :call-me-when-its-important
        :round-house       :o-rly
        :fast-pace         :thats-pretty-bad
        :cocked-pistol     :sirens
        :say-what?))

如果我理解正确,通常键有冒号,值没有。这里的目的是什么?谢谢。

:开头的单词是关键字。关键字充当已知值,例如某些语言中的枚举。你也可以像在Python或JavaScript中那样使用字符串,但关键字有一些不错的功能。

在这种情况下,如果函数收到例如已知关键字:round-house,它将返回已知值:o-rly。其他一些代码反过来知道:o-rly的含义。如果调用explain-defcon-level的代码希望它返回字符串,则不妨使用字符串。

关键词:

  • 可以在地图中查找自己(def m {:abba 1 :beef 2}) .. (:abba m) => 1
  • 易于串(name :foo) => "foo"
  • 很容易用琴弦(keyword "bar") => :bar制成
  • 性能卓越:快速比较,不浪费内存

:只是一个用于创建关键字的阅读器表单。

clojure中的关键字是数据结构,就像符号,字符串或数字一样。

关键字在哈希映射中用作键,因为它们为 invoke(( 实现了 IFn,允许您编写类似 (:mykey my-map) 而不是 (my-map :mykey)(get my-map :mykey) 的东西。

通常,您可以使用任何数据结构作为哈希映射键:

(def my-map
  { {:foo :bar} 1
    {:bar :baz} 2 })
(my-map {:foo :bar}) ; 1

你可以把 clojure 代码想象成由 s 表达式中的许多符号组成。当读取器分析这些表达式时,它必须将符号解析为一个值。其中一些符号是自我评估的,即它们会自我评估。例如,符号"Hello world"是一个字符串符号,它对自身进行评估。数字 123 也是自我评估,并将评估到数字 123。

其他符号需要绑定到一个值。如果你只有符号弗雷德,它需要绑定到某个值,即(def fred "Hello world"(。如果符号是列表中的第一个符号(s-expression(,它必须计算为一个函数,即(def fred (fn ....(或简写(defn fred [] ....(。请注意,这稍微简化了事情,因为您也有宏,但现在可以忽略它们 - 它们是特殊的,实际上,通常被称为特殊形式。

除了字符串和数字,还有另一个非常有用的自我评估符号,关键字。它以前导":"为特征。关键字评估自身,即:fred评估为:fred。

关键字还具有一些非常好的属性,例如快速比较和有效利用空间。当您想要一个表示某物的符号,但又不想在使用之前将其定义(绑定(到某物时,它们也很有用。在哈希映射中,关键字也是哈希映射的一个函数,所以你可以做类似(:mykey maymap(而不是(get mymay :mykey(之类的操作。

通常,每个符号的计算结果必须为

一个值,非引号列表中的第一个符号的计算结果必须为函数。您可以引用列表和符号,这基本上是说"此时不要评估我"。

考虑到这一点,您可以将这些符号中的任何一个用作clojure数据结构中的值,即您可以拥有函数,关键字,字符串,数字等的向量。

在您提供的示例中,您希望 case 语句返回某种符号,然后您可能可以使用该符号在程序的稍后做出某些决定。您可以将返回值定义为字符串,例如"您和谁的军队",然后将其与其他字符串进行比较以做出决定。但是,您甚至可以通过定义类似

(def a "You and whose army")

然后做类似的事情

(= a return-val)

但它并没有真正给你买任何东西。它需要更多的打字、引用、内存,并且比较速度较慢。

当您只是在repl上玩耍并且只想测试一些想法时,关键字通常非常有用。不必写["a"b"cc"]之类的东西,你可以只写[:a :b :c]。

最新更新