2024 Clojure状态调查!中分享您的想法。

欢迎!请参阅关于页面,了解更多关于该网站如何工作的信息。

0投票
Java Interop

有些情况下,我有一个延迟或future返回Java对象,在这种情况下,似乎你只能对从调用点得到的解引用的返回值进行类型注解。

(.reflectionAvoided ^SomeObj @some-delayed-java-object)

是否可以在定义站点对其进行类型注解?如果不是,这是一个合理的功能请求吗?

(def some-delayed-java-object
  (delay (SomeObj.)))

(.someReflectionNeedingMethod @some-delayed-java-object)

谢谢

1 答案

+2投票
by
编辑 by

将这部分包含在一个为您处理注解的函数中。然后使用这个函数而不是直接进行解引用。

user> (set! *warn-on-reflection* true)
true

user> (def the-ref (delay (java.util.HashMap. )))
#'user/the-ref

user> (defn realize-map ^java.util.HashMap [some-ref]
       @some-ref)

#'user/realize-map
user> (doto (realize-map the-ref) (.put :a 2))
{:a 2}

您可以使用协议(或multimethod)来泛化。这里是一个协议示例...

(defprotocol IMapthing
  (retrieve [this arg])
  (insert   [this k v]))

(extend-protocol IMapthing
  clojure.lang.Delay
  (retrieve [this k]   (retrieve @this k))
  (insert   [this k v] (do (insert @this k v) this))
  java.util.HashMap
  (retrieve [this k] (.get this k))
  (insert   [this k v ] (.put this k v)))

user> (def the-delay (delay (java.util.HashMap.)))
#'user/the-delay
user> (insert the-delay :a 2)
#<Delay@2ae7ca5b: {:a 2}>

user> (retrieve the-delay :a)
2

还有其他方案,但这些对我来说是最少侵入性的。

...