什么是clojure' val'返回这个值?

时间:2015-06-11 21:43:36

标签: clojure

我刚刚开始学习clojure,并且已经阅读了一些简单的例子,然后尽力为rtfm提供概念。

但是我对val在下面的示例中所做的事情感到有些困惑。这取自val的Clojure doc示例。

(first {:one :two}) ;; => [:one :two]

此处,密钥为hash-map且值为:one的{​​{1}}正在传递给:two。在幕后,Clojure将此first转换为hash-map sequence。由于此vectors中只有一个vector,因此会返回sequence

[:one :two]

如果我尝试拨打(val (first {:one :two})) ;; => :two (val [:one :two]) ;; => ClassCastException clojure.lang.PersistentVector cannot be cast to java.util.Map$Entry (val {:one :two}) ;; => ClassCastException clojure.lang.PersistentArrayMap cannot be cast to java.util.Map$Entry 一个(我认为)a val(我意识到它实际上是一个"持久阵列地图"),我得到了例外情况如上所示。

我也对以下内容感到困惑:

hash-map

为什么我不能将(first {:one :two}) ;; # => [:one :two] (this is a vector right?) (val [:one :two]) ;; # => ClassCastException (why doesn't this give back the same result as the example above?) 的结果插入(first {:one :two})并得到相同的结果?

此外,页面上列出的另一个示例如下:

val

这是我如何阅读该行。选择(map val {:a 1 :b 2}) ;; => (1 2) array-map。对于每个键值对,请在对上调用{:a 1 :b 2}以返回值。从结果调用val返回sequence。这是阅读问题的正确方法吗?

一如既往,感谢您的帮助。

3 个答案:

答案 0 :(得分:7)

地图序列会产生MapEntry值,如您所述,它们看起来像是可以与矢量进行比较

user=> (= (first {:a 1 :b 2}) [:a 1])
true

但不是同一个班级

user=> (= (class (first {:a 1 :b 2})) (class [:a 1]))
false

因此虽然(first {:a 1})的repl上的输出看起来像一个向量,但它不是MapEntry,所以它可以传递给val,但是向量{ {1}}不能,因此类强制转换异常。

您对地图正在执行的操作在高级别上是正确的,更具体的可能是“对于来自{:a 1:b 2}的序列中的每个条目(这是MapEntry值),请调用函数val每个项目(一个MapEntry),并从结果“。

生成一个序列

这将解释为什么像

[:a 1]

将导致与序列生成user=> (map val '([:a 1] [:b 2])) 元素相同的ClassCastException s,而不是Vector元素。

答案 1 :(得分:6)

val返回地图条目的值,而不是地图。

(first {:one :two})返回第一个地图条目(尽管它似乎只是一个vec)

(map val {:one :two})返回每个条目的值,相当于(vals {:one :two})

答案 2 :(得分:3)

(first {:one :two}) ;; # => [:one :two]  (this is a vector right? No, it's not.)
在这种情况下,

[:one :two]MapEntry,而不是矢量。