Pat*_*ace 15 java overloading clojure
对于此示例Java类:
package foo;
public class TestInterop
{ public String test(int i)
{ return "Test(int)"; }
public String test(Object i)
{ return "Test(Object)"; }
}
Run Code Online (Sandbox Code Playgroud)
当我启动Clojure并尝试调用test(int)方法时,将调用test(Object)方法,因为Clojure会自动将整数写入java.lang.Integer对象.
如何强制Clojure调用test(int)方法?
user=> (.test (new foo.TestInterop) 10)
"Test(Object)"
Run Code Online (Sandbox Code Playgroud)
我想调用类似于Component.add(Component comp, int index)AWT的方法,而是继续调用add(Component comp, Object constraints),因此工具栏上的按钮总是以错误的顺序出现.
Mic*_*zyk 15
关于Freenode的#clojure频道正在讨论这个话题.克里斯·豪瑟(他将发布一个答案,但最终决定他太忙了,不得不这样做)发布了一个Gist,它展示了一个boolean与Object重载方法相关的事情; 事实证明,在某些情况下,除了(boolean ...)强制转换之外,还需要类型提示.讨论非常有启发性,Clojure编译过程中的一些黑暗角落变得非常明亮.(参见下面的IRC日志链接.)
基本上,如果一个对象是在方法调用形式中创建的 - (.foo (Foo.) ...)比方说 - 那个类型提示是不必要的; 同样没有必要将对象构造为封闭let形式的本地值(请参阅下面的更新2和我的Gist版本).但是,如果通过Var查找获得对象,则需要类型提示 - 可以在Var本身上提供,也可以在调用站点上提供用于引用Var的符号.
Gist中的Java代码:
package mypkg;
public class Ugly {
public Ugly(){}
public String foo(boolean i) { return "bool: " + i; }
public String foo(Object o) { return "obj: " + o; }
}
Run Code Online (Sandbox Code Playgroud)
和Clojure代码:
(.foo (mypkg.Ugly.) 5)
;=> "obj: 5"
(.foo (mypkg.Ugly.) true)
;=> "obj: true"
(.foo (mypkg.Ugly.) (boolean true))
;=> "bool: true"
(def u (mypkg.Ugly.))
(.foo u (boolean true))
;=> "obj: true"
(.foo #^mypkg.Ugly u (boolean true))
;=> "bool: true"
Run Code Online (Sandbox Code Playgroud)
注意Clojure编译器如何需要类型提示u才能编译直接方法调用.否则,似乎会生成基于反射的代码,这显然会忽略这样一个事实,即参数在此过程中应该是一个原始的.
我的补充如下(这是我上面的Gist的分支).
;; renamed mypkg.Ugly to foo.TestInterop2 when doing my tests
user> (let [t (foo.TestInterop2.)]
(.foo t (boolean true)))
"bool: true"
;;; type-hinting the Var
user> (def #^foo.TestInterop2 x (foo.TestInterop2.))
#'user/x
user> (.foo x (boolean true))
"bool: true"
Run Code Online (Sandbox Code Playgroud)
这个话题首先提到了这一点.半小时后,Chouser发布了Gist ,之后讨论变得越来越有趣.
user=> (.test (foo.TestInterop.) 10)
"Test(Object)"
user=> (.test (foo.TestInterop.) (int 10))
"Test(int)"
Run Code Online (Sandbox Code Playgroud)
Clojure中的数字通常是盒装的(int => Integer),除非你特别要求原语.
以下是有关Clojure中基元的更多信息.