有件事情我不明白如何使用短符号#(..)匿名函数速记
以下作品匿名函数:
REPL> ((fn [s] s) "Eh")
"Eh"
但这并不:
REPL> (#(%) "Eh")
这工作:
REPL> (#(str %) "Eh")
"Eh"
我不明白的是为什么(#(%)“Eh”)不起作用,同时我也不需要使用str in ((fn [s] s)“嗯“)
他们都是匿名函数,他们都采取,在这里,一个参数。为什么简写符号需要一个函数,而另一个符号不需要?
有件事情我不明白如何使用短符号#(..)匿名函数速记
以下作品匿名函数:
REPL> ((fn [s] s) "Eh")
"Eh"
但这并不:
REPL> (#(%) "Eh")
这工作:
REPL> (#(str %) "Eh")
"Eh"
我不明白的是为什么(#(%)“Eh”)不起作用,同时我也不需要使用str in ((fn [s] s)“嗯“)
他们都是匿名函数,他们都采取,在这里,一个参数。为什么简写符号需要一个函数,而另一个符号不需要?
#(...)
是
(fn [arg1 arg2 ...] (...))
(其中ARGN的数量取决于你有多少个%N在体内)的简写。所以,当你写:
#(%)
它翻译成:
(fn [arg1] (arg1))
注意,这是你的第一个匿名函数,这就好比是不同的:
(fn [arg1] arg1)
你的版本返回Arg1为一个值,扩展速记产生的版本会尝试将其称为函数。你得到一个错误,因为一个字符串不是一个有效的函数。
由于速记在身体周围提供了一组括号,因此它只能用于执行单个函数调用或特殊形式。
当您使用#(...)
时,您可以想象自己写的是(fn [args] (...))
,,其中包括您在英镑之后开始的括号。
所以,你不工作的例子转换为:
((fn [s] (s)) "Eh")
这是因为你试图呼叫字符串“嗯”显然是行不通的。你的例子str
的作品,因为现在你的功能是(str s)
而不是(s)
。 (identity s)
会更接近你的第一个例子,因为它不会强迫str。
这是有道理的,如果你仔细想想,因为比这完全小例子,其他的,每一个匿名函数会调用东西,所以这会是一个有点傻,要求另一组嵌套括号的实际上使一个电话。
至于其他的答案已经非常漂亮指出的那样,你居然张贴#(%)
扩展到像(fn [arg1] (arg1))
,这一点也不一样(fn [arg1] arg1)
。
@约翰平整度指出,你可以使用identity
,但如果你正在寻找一种方式使用#(...)
调度宏写identity
,你可以做这样的:
通过结合#(...)
调度宏与->
threading macro它被扩大到像(fn [arg1] (-> arg1))
,它再次扩大到(fn [arg1] arg1)
,这只是想你想要的东西。我还发现->
和#(...)
宏组合有助于编写返回向量的简单函数,例如:
#(-> [%2 %1])