尽管在 Clojure 中对 Java 构造函数有类型提示,但仍会出现反射警告

Posted

技术标签:

【中文标题】尽管在 Clojure 中对 Java 构造函数有类型提示,但仍会出现反射警告【英文标题】:Reflection warning despite type hint to Java constructor in Clojure 【发布时间】:2019-11-25 16:13:01 【问题描述】:

尽管有类型提示,但以下代码给了我一个反射警告。

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

(IllegalArgumentException.
  ^String (with-out-str (print "hi")))

警告:

Reflection warning ... 
call to java.lang.IllegalArgumentException ctor 
can't be resolved.

代码已从更复杂的示例中提取和简化,其中在with-out-str 中执行漂亮打印任意对象。我正在使用 Clojure 1.10.0。

【问题讨论】:

【参考方案1】:

这是CLJ-865。它不是特定于with-out-str:向任何作为宏调用的形式添加类型提示通常会丢弃它。典型的解决方法是您的答案:定义一个本地保存值,人为地引入非宏形式进行注释。

【讨论】:

我想这不会很快得到解决,因为你在 2011 年报告了它,甚至提供了一个补丁。 毫无疑问,他们总有一天会做到的。【参考方案2】:

Carcigenicate 对原因的洞察力启发了我尝试以下同样有效的方法。

(let [m (with-out-str (print "hi"))]
  (IllegalArgumentException.
   ^String m ))

【讨论】:

【参考方案3】:

我不确定原因,但我会注意到它可以通过调用 str 来解决:

(IllegalArgumentException. (str (with-out-str (print "hi"))))

好像和try有关?:

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

(IllegalArgumentException. ^String (try "" (finally "")))

Reflection warning, C:\Users\slomi\AppData\Local\Temp\form-init3916067866461493959.clj:3:1 - call to java.lang.IllegalArgumentException ctor can't be resolved.

【讨论】:

以上是关于尽管在 Clojure 中对 Java 构造函数有类型提示,但仍会出现反射警告的主要内容,如果未能解决你的问题,请参考以下文章

无论如何在clojure中构造一个lambda函数?

中文书籍中对《人月神话》的引用(十三):Clojure编程软件设计重构软件领导……

在 Clojure 中类型提示一个 nil 文字

使用 Clojure reify 提供构造函数

Clojure 中的惯用错误处理

Clojure:让作用域和函数返回值