一个用Java编写的类是否可以实现一个用Clojure编写的协议?

8

我只能找到关于反向的信息;使用Clojure来实现Java接口。然而,我想要用Clojure编写一个程序,并允许用户用Java进行扩展。例如:

# P.clj
(defprotocol P
  (f [a])
  (g [a b]))

# I.java
public class I implements P {
    public Object f(Object a) { … }
    public Object g(Object a, Object b) { … }
}

还有,我该如何指定参数类型,以便不必在任何地方都使用Object

我目前唯一看到的选择是使用点符号并依赖于鸭子类型,但我更喜欢在Java方面进行编译时验证接口实现。


2
作为一个猜测,我会尝试定义 I<T> 并在所有地方使用 T - Peter Lawrey
避免在各处使用Object的另一种选择是编写一个反映预期实现产生的实际参数和返回类型的Java接口,并使用extend-protocol来允许Java接口的实例满足协议。 - Alex
2个回答

7

是的,这完全可能,并且就像这样。

文档的相关部分:

defprotocol将自动生成一个相应的接口,与协议名称相同,即给定一个协议my.ns/Protocol,一个接口my.ns.Protocol。该接口将具有与协议函数对应的方法,并且协议将自动与接口实例一起工作。

而且,为了回答你的问题:

要想参与协议的Java客户端可以通过实现协议生成的接口来实现最高效的方式。


我在哪里可以找到接口生成的类文件或Java源文件? - user1804599
@rightfold 你需要对定义协议的命名空间进行AOT编译,以生成 .class 文件。请参阅 http://clojure.org/compilation - Alex
可能唯一有效地使用生成的类的方式是通过某种实现它的IDE生成的类。 - BillRobertson42

2
如Isaac所说,是的。
但是,如果没有源代码表示,我认为这种说法有点扯淡。请注意,我不是指Isaac的回答。我指的是Clojure在这种情况下的工作方式。
如果您需要Java互操作性,您可能希望坚持使用无聊的Java接口。我认为这也会使在JVM中与其他语言进行互操作更容易,因为它是最常见的分母。我还认为这使得与非Clojure开发人员进行沟通更加容易。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接