除了地图和向量之外,还有其他在Clojure中使用get的用途吗?

时间:2017-07-08 04:01:43

标签: dictionary vector clojure get

到目前为止,我所知道的用途是向量:

(get [1 2 3 4] 2) ; => 3

并在地图上:

(get {:a "a" :b "B" :c "c"} :c) ; => "c"

从文档中说:

  

clojure.core / get([map key] [map key not-found])

     

如果键不存在,则返回映射到key,not-found或nil的值。

2 个答案:

答案 0 :(得分:9)

除了地图和向量之外, get 的常见用法是在字符串上:

(get "Cthulhu" 2) ;; => \h

get 也适用于集合和本机Java(脚本)数组。 ClojureScript和JavaScript互操作中的一种可能用法:

(def js-array (-> (js/Array 10) ;Create and fill native JS array
                  (.fill "a")
                  (.map (fn [_ i] i))))
(get js-array 3) ; => 3

作为另一个例子,get用于按集合中的项目查找:

(get #{:b :c :a} :c) ;;=> :c

请注意,它不适用于(已排序)的集合和索引,例如:

(get (sorted-set :b :a :c) 1) ;; throws exception

此外,地图,向量和集合充当其成员的功能,因此您通常可以完全避免使用 get

(#{:a :b :c} :b) ; => :b
({:a 1 :b 2 :c 3} :b) ; => 2
([:a :b :c] 1) ; => :b

使用 get 的优势在于您可以提供默认值:

(get {:a :b :c} :d) ; => nil
(get {:a :b :c} :d :not-found) ; => :not-found

另请参阅@Thumbnail's answer以了解 get 如何在幕后工作。

答案 1 :(得分:3)

@ToniVanhanla's answer之后,对于JVM,相关的Clojure接口为clojure.lang.ILookup

正如美国人所说的那样,看起来,

  • Clojure get转换为对clojure.lang.RT/get的调用。
  • 如果可能,这会转换为ILookup并调用相应的内容 valAt方法。
  • 如果没有,则会调用...RT/getFrom
  • ......其条款明确涉及,
    • Java地图,
    • Clojure设置,
    • Java字符串和数组。

如果这些都不适合,则返回nil

Java数组没有父接口:它们都直接从Object下降。它们由Java的Class/isArray

检测到

有些令人惊讶的是,Clojure get不适用于Vector s等Java集合:

(java.util.Vector. (seq "Hello, world!"))
=> [\H \e \l \l \o \, \space \w \o \r \l \d \!]

但是

(get (java.util.Vector. (seq "Hello, world!")) 4)
=> nil