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

Kur*_*ler 6 clojure

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

但是我对val以下示例中的操作感到有点困惑.这是从val的Clojure doc示例中获得的.

(first {:one :two}) ;; => [:one :two]
Run Code Online (Sandbox Code Playgroud)

这里,传递的是hash-map:one和值的a .在幕后,Clojure的转换这到的.由于只有一个在此,它返回.:twofirsthash-mapsequencevectorsvectorsequence[: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
Run Code Online (Sandbox Code Playgroud)

如果我试着调用val(我认为)a 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?)
Run Code Online (Sandbox Code Playgroud)

为什么我不能只是插上的结果(first {:one :two})val,并得到同样的结果?


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

(map val {:a 1 :b 2}) ;; => (1 2)
Run Code Online (Sandbox Code Playgroud)

这是我读行的方式.拿走array-map {:a 1 :b 2}.对于每个键值对,调用val该对以返回该值.sequence从结果调用中返回a map.这是阅读问题的正确方法吗?

一如既往,感谢任何和所有的帮助.

Mar*_*her 7

一个地图序列产生MapEntry你所注意到的值,它们看起来像并且可以与矢量进行比较

user=> (= (first {:a 1 :b 2}) [:a 1])
true
Run Code Online (Sandbox Code Playgroud)

但不是同一个班级

user=> (= (class (first {:a 1 :b 2})) (class [:a 1]))
false
Run Code Online (Sandbox Code Playgroud)

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

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

这将解释为什么会这样

user=> (map val '([:a 1] [:b 2]))
Run Code Online (Sandbox Code Playgroud)

将导致与ClassCastException序列生成Vector元素相同的s ,而不是MapEntry元素.


Fab*_*tor 6

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

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

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