假设我们有一个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.RuntimeException:无法在此上下文中解析符号:foo,编译......:
但如果我试着引用符号
(f 'foo)
它会产生不同但预期的错误:
IllegalArgumentException找不到匹配的字段:类com.dullesopen.srl.FunCall的方法clojure.lang.Reflector.getInstanceField(Reflector.java:271)
错误是预期的,因为根据特殊形式的文档。 (点)假设第二个参数匹配字段或方法的名称,因此它不是来自Clojure观点的实际符号。
以下方法解决了问题,但我不喜欢额外的memfn
。对我来说,它表明Java方法实际上并不是Clojure中的第一类对象。
(defn f [method]
(method (new FunCall)))
(f (memfn foo))
所以问题是:有没有办法表明""到特殊形式.
第二个参数应该以某种方式解析/评估以获得方法名称?或者也许还有另外一个类似dot的特殊但第二个参数已解决?
答案 0 :(得分:3)
你的理解是正确的, java方法实际上不是clojure中的第一类公民。你不能独立于它的类传递方法。我能想到的最接近的是传递了解类和方法的函数,或者使用宏来为每个类构建对方法的调用。如果你不喜欢上面的方法(这看起来对我很好),那么 这可以直接使用宏来完成,但我个人更喜欢你的方法:
user> (defmacro f [method]
`(. (String. "asdf") ~method))
#'user/f
user> (f hashCode)
3003444
PS:memfn
被函数文字语法取代。它很少使用。