Zau*_*bov 13 clojure map destruction keyword-argument
考虑具有以下签名的函数:
(defn make-widget [& {:keys [x y] :or {x 10 y 20}}]
...)
Run Code Online (Sandbox Code Playgroud)
将地图传递给函数的最佳方法是什么,例如:
(make-widget {:x 100})
Run Code Online (Sandbox Code Playgroud)
要么
(make-widget {:y 200 :x 0})
Run Code Online (Sandbox Code Playgroud)
目前有什么我想到的是通过vec,flatten并apply如:
(apply make-widget (flatten (vec ({:x 100}))
Run Code Online (Sandbox Code Playgroud)
我坚信有更好的方法可以做到这一点.你能考虑一下吗?
Rör*_*örd 11
我想不出更优雅的方式,尽管在我看来应该有一个(比如地图特定的变体apply).
flatten然而,使用有一些问题,而不是非常优雅.如果你的地图的价值是集合,那么它们flatten也会以递归方式工作,所以事情可能完全混淆了.这个替代方案避免了这个问题:
(apply make-widget (apply concat {:x 100}))
Run Code Online (Sandbox Code Playgroud)
还有一个已知的(至少不是我发明的),功能"mapply":
(defn mapply [f & args] (apply f (apply concat (butlast args) (last args))))
Run Code Online (Sandbox Code Playgroud)
哪个可以应用
(mapply your-function {:your "map"})
Run Code Online (Sandbox Code Playgroud)
至于为什么Clojure核心缺少这种特定于语言的功能,更加原生和优雅地实现,没有人能给我一个明确的答案.
UPDATE
在Clojure上花了很多时间编程后,我个人倾向于避免创建接受{}一个vararg的函数.虽然起初这看起来很吸引人,但实际上经验证明,{}由于许多原因,传递明确总是更好.