我只是在学习语言而且我有一个简单的问题。为什么这样做(构造{:key "value"}
):
(#(assoc {} :key %) "value")
但这并不是:
(#({:key %}) "value")
ArityException Wrong number of args (0) passed to: PersistentArrayMap clojure.lang.AFn.throwArity (AFn.java:429)
在Python上,后一种语法完全有效:
> (lambda v: {'key': v})('value')
{'key': 'value'}
编辑:感谢您提供了很好的答案,显然我需要不再将#
视为与Python中的lambda
等效。
答案 0 :(得分:6)
#(f %)
由读者扩展为(fn [%] (f %)
。同样,#({:key %})
也会扩展为(fn [%] ({:key %})
。与此类似的python将是lambda v: {'key': v}()
,它与Clojure版本具有完全相同的问题。
您要找的是等同于(fn [v] {:key v})
的东西。如果您确实想使用#(...)
表示法,可以使用#(do {:key %})
。
顺便说一句,我个人从不使用#(...)
。我认为这很难(例如这个证据的例子),并且只比同等的fn
形式更紧凑。然后还有#(...)
形式无法嵌套的限制。
答案 1 :(得分:4)
这是#()
读者的限制。 fn
可以正常使用。
user=> ((fn [x] {:key x}) "value")
{:key "value"}
答案 2 :(得分:0)
{:key %}
是PersistentArrayMap。你有"动词位置"在你的函数调用中。你需要一种类型的Clojure方法来避免这种错误,正如你在第一个(工作)例子中看到的那样。