【问题标题】:What does clojure 'val' return this value?clojure 'val' 返回这个值是什么?
【发布时间】:2015-06-11 21:43:36
【问题描述】:

我刚刚开始学习 clojure,一直在阅读一些简单的示例,然后尽我所能使用 rtfm 获取概念。

但是,我对val 在下面的示例中所做的事情有点困惑。这取自 val 的 Clojure 文档示例。

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

这里,一个带有:one 键和:two 值的hash-map 被传递给first。在幕后,Clojure 将这个 hash-map 转换为 sequencevectors。由于这个sequence中只有一个vector,所以返回[: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

如果我尝试在(我认为)hash-map(我意识到它实际上是一个“持久数组映射”)上调用 val,我会得到如上所示的异常。

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

(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 以返回值。从对map 的结果调用中返回sequence。这是阅读问题的正确方法吗?

一如既往,感谢您提供的所有帮助。

【问题讨论】:

  • 映射条目是向量,但并非所有向量都是映射条目。 val 仅适用于地图条目。
  • ... 也就是说,(type (first {:one :two})) => clojure.lang.MapEntry

标签: clojure


【解决方案1】:

如您所述,地图序列会产生 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,但是向量[:a 1]不能,因此类转换异常。

您对 map 正在执行的操作的理解在较高级别上是正确的,更具体的可能是“对于来自 {:a 1 :b 2} 的序列中的每个条目(它们是 MapEntry 值)调用函数 val on每个项目(一个 MapEntry),并从结果中生成一个序列”。

这将解释为什么类似

user=> (map val '([:a 1] [:b 2]))

将导致相同的ClassCastExceptions 序列生成Vector 元素,而不是MapEntry 元素。

【讨论】:

    【解决方案2】:

    val 返回映射条目的值,而不是映射。

    (first {:one :two}) 返回第一个映射条目(虽然它看起来只是一个 vec)

    (map val {:one :two})返回每一项的值,相当于(vals {:one :two})

    【讨论】:

      【解决方案3】:
      (first {:one :two}) ;; # => [:one :two]  (this is a vector right? No, it's not.)
      

      [:one :two] 在这种情况下是 MapEntry,而不是向量。

      【讨论】:

        猜你喜欢
        • 2018-04-07
        • 2017-11-25
        • 2018-09-02
        • 1970-01-01
        • 1970-01-01
        • 2013-11-29
        • 2014-08-17
        • 2022-12-03
        • 2019-12-26
        相关资源
        最近更新 更多