考虑.indexOf
功能。如果我只需要立即使用该功能,我就可以调用(.indexOf [1 2 3] 2)
。但是如果我想将函数作为参数传递给其他函数,例如map?以下不起作用,返回CompilerException“无法解析符号”:
(map .indexOf [[1 2 3] [4 5 6]] [2 4])
显然我可以在一些匿名函数中包含对.indexOf
的调用以达到同样的效果:
(map #(.indexOf %1 %2) [[1 2 3] [4 5 6]] [2 4])
但那不是我要问的。有没有其他方法可以引用.indexOf
,这样就不需要包装函数了?如果这是不可能的,有没有理由不支持这个?
答案 0 :(得分:5)
Clojure函数是IFn接口的实例,这意味着它们可以被调用。另一方面,java方法不实现接口,不能用作高阶函数。
正如Alister Lee指出的那样,你可以使用memfn来包装方法调用。但是如果你检查 documentation,你会发现你提到的匿名函数方法是你要求的首选方法。
答案 1 :(得分:2)
首先.indexOf
不是函数。摘录
(.indexOf [1 2 3] 2)
或等效表格
(. [1 2 3] indexOf 3)
被称为Dot特殊形式。特殊表单不会通过与函数应用程序相同的规则进行评估。在这种情况下,特殊规则是第一个参数被视为目标对象,第二个参数(如果它是符号)被假定为目标对象上的方法或字段。现在,很清楚为什么.indexOf
不是有效的符号或函数。
你是对的,我们可以使用第一类函数包装成员访问,并在map
方法中使用它。正如Alister Lee上面提到的那样,memfn
对于这个目的很方便:
(map (memfn indexOf elem) [[1 2 3] [4 5 6]] [2 4])
答案 2 :(得分:1)
Java方法并非设计为第一类函数。它们不像第一类函数那样,也不像它们那样实现。没有类传递java方法并没有多大意义。
因此Clojure可以是一种函数式语言,它创建的东西是第一类函数,它们可以在不需要拥有类的情况下使用和传递(实现它们是单例类,因为我们必须使用JVM的实施的事物模型。)
如果我们试图让Java方法像clojure的第一类函数一样,那么我们必须为函数提供一个不那么强大的基础(降低函数的标准,使它们真的像方法一样),或者一堆繁琐的记忆方法功能与实际功能的特殊情况例外。我们做出的决定是,我们最好承认方法从来就不是真正的功能,而不是像对待它们那样对待它们。特别是当一个函数中的方法调用很容易时(如你所示)。
答案 3 :(得分:0)
只有一个澄清
“。indexOf”不是一个函数,而是一个“点”加上“name function或instanceMember”。我的意思是在这种情况下函数是这些元素的并集,所以你的“名称函数”需要java对象,它将实际函数的上下文化。
祝你好运 涓答案 4 :(得分:0)
我不知道 - 但不应该
(def j-fn #(.indexOf %1 %2))
(j-fn "foox" "x")
;=> 3
你真的按照自己的意愿行事吗? 基本上将它包装在anon-fn
中