Clojure 将Java方法作为参数传递
假设我们有一个Java类:Clojure 将Java方法作为参数传递,clojure,clojure-java-interop,Clojure,Clojure Java Interop,假设我们有一个Java类: public class Fun { public int foo () { return 1; } public int bar () { return 2; } } 以下代码在Clojure中不起作用: (defn f [method] (. (new Fun) method)) (f foo) 产生预期错误(此处无问题): CompilerException java.lang.RuntimeExcept
public class Fun {
public int foo () {
return 1;
}
public int bar () {
return 2;
}
}
以下代码在Clojure中不起作用:
(defn f [method]
(. (new Fun) method))
(f foo)
产生预期错误(此处无问题):
CompilerException java.lang.RuntimeException:无法解析符号:foo在此上下文中,正在编译…:
但如果我试着引用这个符号
(f 'foo)
它会产生不同但也是预期的错误:
IllegalArgumentException未找到匹配字段:类com.dullesopen.srl.FunCall clojure.lang.Reflector.getInstanceField的方法(Reflector.java:271)
该错误是预期的,因为根据特殊表格中的文档。(dot)假定第二个参数与字段或方法的名称匹配,因此从Clojure的角度来看,它不是实际的符号
下面的方法解决了这个问题,但我不喜欢额外的memfn
。对我来说,它表明Java方法实际上不是Clojure中的第一类对象
(defn f [method]
(method (new FunCall)))
(f (memfn foo))
所以问题是:有没有一种方法可以“指示”特殊形式
,第二个参数应该以某种方式解析/计算以获得方法名?或者可能还有另一个类似于dot的特殊情况,但第二个参数已解决?您的理解是正确的,java方法在clojure中实际上不是一等公民。不能独立于方法的类传递方法。我能想到的最接近的方法是传递同时了解类和方法的函数,或者使用宏为每个类构建对方法的调用。如果你不喜欢上面的方法(我觉得很好),那么
这可以通过宏直接完成,但我个人更喜欢您的方法:
user> (defmacro f [method]
`(. (String. "asdf") ~method))
#'user/f
user> (f hashCode)
3003444
PS:memfn
被函数文本语法替换。它很少被使用