我有一些Clojure代码试图通过几层Java代码进行互操作(在这种情况下,java.nio.Path通过以下方式java.nio.file.WatchEvent<?>:
(defn unroll-event
[^WatchEvent event]
{ :kind (.kind event)
:context (.context event)
:path (-> event .context .toAbsolutePath .toString)})
Run Code Online (Sandbox Code Playgroud)
在这段代码中,我有类型暗示event,所以我认为它应该能够弄清楚.context应该返回什么,因此,能够弄清楚做什么.toAbsolutePath和.toString做什么.我想在这种情况下,因为.context定义了返回泛型类型T,我想知道我是否可以键入提示调用.context.我试着只是前面加上^java.nio.file.Path来.context,并^Path和^String以.toAbsolutePath和toString,分别,但我仍然得到的警告:
Reflection warning, junkcode/core.clj:28 - reference to field toAbsolutePath can't be resolved.
Reflection warning, junkcode/core.clj:28 - reference to field toString can't be resolved.
Run Code Online (Sandbox Code Playgroud)
在这种情况下我能做些什么吗?是因为它->是一个宏,并且在其中有类型提示的特殊规则?
(-> x .blah ^String .bar)基本上扩展到(^String .bar (.blah x)),这显然不是您想要提示的地方。关键是类型提示在任何上下文(例如宏)中都没有特殊行为:它只是应用于源代码符号的元数据。在您的示例中->,您无法在输入表单上放置元数据,从而使其位于输出表单中您想要的位置。因此,您需要编写其他形式,(-> ^Path (.context event) .toAbsolutePath str)例如 。
另外,Clojure 的推理器对泛型类型一无所知,因此方法返回 T 被视为方法返回对象,这解释了为什么您需要在这里进行提示。