快捷方式以初始化clojure的地图



所以在ES6中,我可以做这样的事情:

let x=1 y=1 z=1
let o = {x, y,z}
console.log(o.x)  //prints 1

我看不到任何内置的方式可以在Clojure中做类似的事情。可以比这更好地从需要多个参数的函数返回地图吗?

(defn foo
  [x y z]
  {:x x :y y :z z})
(pprint (get  ( foo 1 2 3) :x)) ;prints 1

有十几个原因是这样做不是一个好主意,但是关于LISP的很酷的事情是您可以做自己想做的事,如果语言不做什么您想要,可以扩展它。

这是一个简单的宏

(defmacro infer-map [& args]
  {:pre [(every? symbol? args)]}
  `(hash-map
     ~@(interleave
         (map (comp keyword name) args)
         args)))

和用法:

(let [x 1 y 2 z 3]
  (infer-map x y z))
=> {:y 2, :z 3, :x 1}

您可以在tupelo clojure库中使用vals->contextwith-context进行此操作。单元测试显示此功能在行动中:

(dotest
  (let [ctx     (let [a 1
                      b 2
                      c 3
                      d 4
                      e 5]
                  (vals->context a b c d e)) ]
    (is= ctx {:a 1 :b 2 :c 3 :d 4 :e 5})
    (let [{:keys [a b c d e]} ctx]
      (is= [a b c d e] [1 2 3 4 5]))
    (with-context ctx [a b c d e]
      (is= [a b c d e] [1 2 3 4 5])
      (is= 15 (+ a b c d e)))
    (with-context ctx [b a d c e] ; order doesn't matter
      (is= [a b c d e] [1 2 3 4 5])
      (is= 15 (+ a b c d e)))
    (throws?
      (with-context ctx [x y z]
        (println "shouldn't ever get here")))))

最新更新