我们可以这样定义和使用匿名函数:
repl=> (#(+ 10 %) 1)
11
但是
->
宏将不接受此类匿名函数。假设我要加10,然后乘以2。我尝试写:(-> 5 #(+ 10 %) #(* 2 %))
但是由于某些原因,这不是正确的代码,正确的代码是
(-> 5 (+ 10) (* 2))
(+ 10)
和#(+ 10 %)
有什么区别,为什么->
宏不能接受用#()
定义的匿名函数? 最佳答案
这是我的解释尝试。有两个部分。
首先,匿名文字语法。编写#(+ 10 %)
时,它会扩展为功能类似于以下内容的内容:
(fn [x] (+ 10 x))
对于前。
=> (macroexpand '(#(+ 10 %))
将返回类似:
(fn* [p1__7230#] (+ 10 p1__7230#))
第二部分。当您使用线程宏作为docs say时,宏会通过将第一个参数作为第二项插入第一种形式来扩展。并且如果还有更多表格,则将第二个表格中的第一个表格作为第二个项目插入,依此类推。
这里的关键是第二项。它并不在乎您提供什么形式的参数,它只会使用该规则进行扩展。
因此,当您使用时要结合这两点
(-> 5 #(+ 10 %) #(* 2 %))
遵循规则,它被扩展为功能类似于此的东西
(fn (fn 5 [x] (+ 10 x)) [y] (* 2 y))
不会编译。
另外,请注意,
(+ 10)
格式不是匿名函数。这是一个局部函数调用,在宏扩展过程中会使用参数进行更新。所谓“部分”,是指字面意义,而不是功能编程意义。更新资料
为了解释当您将匿名文字括在括号中时(如对问题的评论所述),为什么它起作用,您可以从这两个规则推断出结果。对于前。
=> (macroexpand '(#(+ 10 %)))
将导致功能等效
((fn [x] (+ 10 x)))
因此,当一个项目插入第二个位置时,它看起来像
((fn [x] (+ 10 x)) 5)
相当于
(#(+ 10 %) 5)
关于clojure - 为什么匿名函数定义语法不同?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32836705/