在注释clojang时,我遇到了调用重载Java方法的协议方法的问题。我已经将问题从'clojang.jinterface.otp.nodes
缩小到以下最小的棘手案例:
(ns clojang.jinterface.otp.nodes
(:require [clojure.core.typed :as t :refer [ann ann-protocol]]
[clojure.core.typed.utils :refer [defprotocol]])
(:import [com.ericsson.otp.erlang OtpTransport]
[java.net InetAddress])
(:refer-clojure :exclude [defprotocol]))
(ann-protocol AbstractNodeObject
create-transport
(t/IFn [AbstractNodeObject InetAddress int -> (t/Nilable OtpTransport)]
[AbstractNodeObject String int -> (t/Nilable OtpTransport)]))
(defprotocol AbstractNodeObject
(create-transport [this addr port-num]
"Create instance of ``OtpTransport``."))
(extend-type AbstractNode
AbstractNodeObject
(create-transport [this addr port-num]
(.createTransport this addr port-num)))
根据JInterface Javadocs,AbstractNode.createTransport
可以将java.lang.String
或java.net.InetAddress
作为addr
。虽然我相信我已经在ann-protocol
形式中正确地注释了这一点,core.typed
抱怨实现(在示例的最后一行)。我怀疑我可以用t/inst
以某种方式解决这个问题,但还没有弄清楚确切的咒语。
我知道我可以将类型提示^String
或^InetAddress
添加到arglist(在示例的倒数第二行),并从相应的t/IFn
中删除另一个子句上面的表格,但我怎么能告诉core.typed
这两种类型是否可行?
答案 0 :(得分:2)
在与安布罗斯就IRC进行简短讨论后,我们已达成的解决方案是在(string? addr)
上进行如下分支:
(create-transport [this addr port-num]
(if (string? addr)
(.createTransport this ^String addr port-num)
(.createTransport this ^InetAddress addr port-num)))
并将IFn
注释替换为:
[AbstractNodeObject (t/U String InetAddress) int -> (t/Nilable OtpTransport)]