Clojure匿名函数报错解惑:两种写法为何表现不同?
Clojure匿名函数简写的核心差异解析
先看你贴的REPL执行结果:
user=> ((fn [x] x) 5)
5
user=> (#(%) 5)
Execution error (ClassCastException) at user/eval1576$fn (REPL:1).
class java.lang.Long cannot be cast to class clojure.lang.IFn...
两种写法的本质差异一目了然:
(fn [x] x)定义的是一个接受参数x并直接返回x的匿名函数,调用时传入5,自然返回5。#(%)是Clojure的匿名函数简写,它展开后等价于(fn [%] (%))——也就是定义了一个接受参数%(第一个参数的占位符),然后把这个参数当作函数去调用的匿名函数。
所以执行(#(%) 5)时,实际是把5传入这个匿名函数,函数体执行(5),试图把Long类型的5当作函数调用,这就触发了类型转换异常——因为Long并不是Clojure的函数类型(IFn)。
如果想用简写实现和(fn [x] x)等价的效果,应该写#%,这才是“返回第一个参数”的简写形式,执行(#% 5)就会返回5,和第一个写法结果一致。
内容的提问来源于stack exchange,提问作者user1785730
相关产品推荐
相关产品推荐

