所以在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->context
和with-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")))))