为什么不(进入{} x)接受x的序列序列

时间:2014-01-16 10:08:51

标签: clojure

=> (into {} (for [x [["1" "2"] ["3" "4"]]] (map #(Long/parseLong %) x)))
ClassCastException java.lang.Long cannot be cast to java.util.Map$Entry  clojure.lang.ATransientMap.conj (ATransientMap.java:44)

=> (into {} (for [x [["1" "2"] ["3" "4"]]] (seq (map #(Long/parseLong %) x))))
ClassCastException java.lang.Long cannot be cast to java.util.Map$Entry  clojure.lang.ATransientMap.conj (ATransientMap.java:44)

=> (into {} (for [x [["1" "2"] ["3" "4"]]] (vec (map #(Long/parseLong %) x))))
{1 2, 3 4}

我有两个相关的问题:

  1. 为什么(into {})坚持将vector作为(键,值)对的容器?
  2. 为什么要尝试使用Long作为对子的组成部分?它不应该至少抱怨看到一个非向量,不管它包含什么?

  3. 使用Clojure 1.5.1进行BTW测试。

2 个答案:

答案 0 :(得分:4)

into已在conj

之上实施
(into {} ...) ;; equivalent to (below)
(-> {}
    (conj (map #(Long/parseLong %) ["1" "2"])  ;; produces the same exception
    (conj (map #(Long/parseLong %) ["3" "4"]))

conj要求地图,地图条目或双元素向量。请考虑http://clojure.org/data_structures#toc17的摘录:

  

conj期望另一个(可能是单个条目)地图作为项目,并返回一个新地图,即旧地图加上新地图,这可能会覆盖旧地图的条目。 conj还接受MapEntry或两个项目(键和值)的向量。

答案 1 :(得分:4)

回答第二个问题:你将一系列序列传递给intointo通过重复conj(或conj!来工作,如果可能的话,结果是等效的)。在每一步中,您将从序列序列中获取一个项目,并conj将其添加到地图上。每个这样的项目是两个Long s的序列。当您将conj序列放到地图上时,conj会假定它是一系列地图条目,并将每个元素强制转换为Map$Entry。 所以,在这里,它会尝试将Long转换为Map$Entry