为什么我不能在->
的链式通话中使用部分功能或匿名功能?
(->
"123"
seq
sort
reverse
(partial apply str))
=> #<core$partial$fn__4230 clojure.core$partial$fn__4230@335f63af>
我原本以为会创建部分函数并立即应用于上一个函数的结果,但它实际上是自己返回的。
使用一个参数进行简单的函数链接当然可以正常工作:
(->
"123"
seq
sort
reverse
clojure.string/join)
答案 0 :(得分:2)
->
宏定义为:
(doc ->)
-------------------------
clojure.core/->
([x & forms])
Macro
Threads the expr through the forms. Inserts x as the
second item in the first form, making a list of it if it is not a
list already. If there are more forms, inserts the first form as the
second item in second form, etc.
因此(apply str)会产生错误,因为前一个函数的列表是作为第二个参数输入的:
(->
"123"
seq
sort
reverse
(apply str))
ClassCastException clojure.lang.PersistentList cannot be cast to clojure.lang.IFn clojure.core/apply (core.clj:624)
相反,应该使用宏 - &gt;&gt;,它适用于最后一项:
clojure.core/->>
([x & forms])
Macro
Threads the expr through the forms. Inserts x as the
last item in the first form, making a list of it if it is not a
list already. If there are more forms, inserts the first form as the
last item in second form, etc.
然后apply
的解决方案如下所示:
(->>
"123"
seq
sort
reverse
(apply str))
=> "321"
更新:->
和->>
的扩展版本:
(macroexpand-1 '(->>
"123"
seq
sort
reverse
(apply str)))
=> (apply str (reverse (sort (seq "123"))))
从扩展版本中可以看出,表单(apply str)的解释方式只有区别。使用->
插入第二项,而->>
插入最后一项。
(macroexpand-1 '(->
"123"
seq
sort
reverse
(apply str)))
=> (apply (reverse (sort (seq "123"))) str)
答案 1 :(得分:2)
由于->
和->>
只是宏,您可以使用->
测试macroexpand-1
展开的内容(请注意引用&#39;)
user=> (macroexpand-1 '(->
"123"
seq
sort
reverse
(partial apply str)))
(partial (reverse (sort (seq "123"))) apply str)
这就是为什么你得到一个函数而不是一个字符串 - 结果是从reverse
和apply
str
作为参数返回的部分集合(这是一个函数)
如果由于某种原因你需要在->
中应用一个函数,你应该把它包在parens中:
user=> (macroexpand-1 '(->
"123"
((partial sort)) ; we add parens around so -> have plase to insert
))
((partial sort) "123")
或者您可以使用->>
宏,因为它与partial
执行相同的工作:
((partial str "hello ") "world")
"hello world"
和
(->> (str "hello ") "world") ; expands to (str "hello " "world")
"hello world"