如何在 clojure 中添加类型提示来修复 "ctor can't be resolved" 反射警告,即调用构造函数?
How can I add a typehint in clojure to fix "ctor can't be resolved" reflection warning, i.e call to a constructor?
以下示例函数使用 Clojure 的 java 互操作的特殊形式来调用 class 构造函数,导致反射警告:
(defn test-reflection-err []
(new java.util.HashMap {}))
该消息内容如下:
Reflection warning, /Users/ethan/Projects/scicloj/tablecloth.time/src/tablecloth/time/index.clj:26:3 - call to java.util.HashMap ctor can't be resolved.
我已经尝试放置类型提示来避免这种情况,但我不确定将它们放置在何处以防止反射错误。有人知道怎么做吗?
我试过:
(defn test-reflection-err []
(^TreeMap new java.util.HashMap {}))
和
(defn test-reflection-err []
(doto ^TreeMap (new java.util.HashMap {})))
除非您出于某种原因确实需要消除所有反射,否则最简单的答案是将此行放在您的 project.clj
:
:global-vars {*warn-on-reflection* false}
当使用空的 Clojure 映射作为构造函数 arg 时,我无法获得消除警告的类型提示。观察这段代码:
(ns tst.demo.core
(:use demo.core tupelo.core tupelo.test))
(dotest
(newline)
(spyxx {:a 1}) ; `spyxx` prints expression, type, and value
(newline)
(spyxx (java.util.HashMap.)) ; Works
(spyxx (new java.util.HashMap)) ; Works
(newline)
(let [m ^java.util.Map {}]
(spyxx (new java.util.HashMap m)) ; Reflection Warning
(spyxx (java.util.HashMap. m))) ; Reflection Warning
(newline)
(let [^java.util.Map m {}]
(spyxx (new java.util.HashMap m)) ; Works
(spyxx (java.util.HashMap. m)))) ; Works
(def ^java.util.Map m3 {})
(dotest
(newline)
(spyxx m3)
(spyxx (java.util.HashMap. m3))) ; Works
结果如下。请注意,所有这些都有效,但您会在上面指示的位置收到反射警告:
--------------------------------------
Clojure 1.10.2-alpha1 Java 15
--------------------------------------
Testing tst.demo.core
{:a 1} => <#clojure.lang.PersistentArrayMap {:a 1}>
(java.util.HashMap.) => <#java.util.HashMap {}>
(new java.util.HashMap) => <#java.util.HashMap {}>
(new java.util.HashMap m) => <#java.util.HashMap {}>
(java.util.HashMap. m) => <#java.util.HashMap {}>
(new java.util.HashMap m) => <#java.util.HashMap {}>
(java.util.HashMap. m) => <#java.util.HashMap {}>
m3 => <#clojure.lang.PersistentArrayMap {}>
(java.util.HashMap. m3) => <#java.util.HashMap {}>
您似乎不需要空的 Clojure 映射作为构造函数 arg,然后问题就消失了。您还可以通过将 *warn-on-reflection*
设置为 false(在 project.clj
中或在代码中手动设置)来使警告消失。
如果你使用类型提示,很容易在错误的地方得到它,它会被默默地忽略。
更新
考虑这个额外的代码:
(dotest
(newline)
(set! *warn-on-reflection* false) ; not executed upon parsing
(let [m4 ^java.util.Map {}]
(spyxx (new java.util.HashMap m4)) ; Reflection Warning
(spyxx (java.util.HashMap. m4)))) ; Reflection Warning
(newline)
; vvv executed when parsed before following lines
(set! *warn-on-reflection* false)
(let [m5 ^java.util.Map {}]
(spyxx (new java.util.HashMap m5)) ; Works
(spyxx (java.util.HashMap. m5))) ; Works
第一个测试在解析时生成反射警告(测试之前是 运行),因为解析器似乎正在计算常量表达式(推测)。
第二个测试不会生成警告,因为 Clojure 正在依次读取、解析和评估每个表单。因此调用 (set! *warn-on-reflection* false)
在读取和评估以下行之前执行以禁用警告。
您需要在构造函数参数中添加一个提示:
(let [^java.util.Map m {}]
(new java.util.HashMap m))
以下示例函数使用 Clojure 的 java 互操作的特殊形式来调用 class 构造函数,导致反射警告:
(defn test-reflection-err []
(new java.util.HashMap {}))
该消息内容如下:
Reflection warning, /Users/ethan/Projects/scicloj/tablecloth.time/src/tablecloth/time/index.clj:26:3 - call to java.util.HashMap ctor can't be resolved.
我已经尝试放置类型提示来避免这种情况,但我不确定将它们放置在何处以防止反射错误。有人知道怎么做吗?
我试过:
(defn test-reflection-err []
(^TreeMap new java.util.HashMap {}))
和
(defn test-reflection-err []
(doto ^TreeMap (new java.util.HashMap {})))
除非您出于某种原因确实需要消除所有反射,否则最简单的答案是将此行放在您的 project.clj
:
:global-vars {*warn-on-reflection* false}
当使用空的 Clojure 映射作为构造函数 arg 时,我无法获得消除警告的类型提示。观察这段代码:
(ns tst.demo.core
(:use demo.core tupelo.core tupelo.test))
(dotest
(newline)
(spyxx {:a 1}) ; `spyxx` prints expression, type, and value
(newline)
(spyxx (java.util.HashMap.)) ; Works
(spyxx (new java.util.HashMap)) ; Works
(newline)
(let [m ^java.util.Map {}]
(spyxx (new java.util.HashMap m)) ; Reflection Warning
(spyxx (java.util.HashMap. m))) ; Reflection Warning
(newline)
(let [^java.util.Map m {}]
(spyxx (new java.util.HashMap m)) ; Works
(spyxx (java.util.HashMap. m)))) ; Works
(def ^java.util.Map m3 {})
(dotest
(newline)
(spyxx m3)
(spyxx (java.util.HashMap. m3))) ; Works
结果如下。请注意,所有这些都有效,但您会在上面指示的位置收到反射警告:
--------------------------------------
Clojure 1.10.2-alpha1 Java 15
--------------------------------------
Testing tst.demo.core
{:a 1} => <#clojure.lang.PersistentArrayMap {:a 1}>
(java.util.HashMap.) => <#java.util.HashMap {}>
(new java.util.HashMap) => <#java.util.HashMap {}>
(new java.util.HashMap m) => <#java.util.HashMap {}>
(java.util.HashMap. m) => <#java.util.HashMap {}>
(new java.util.HashMap m) => <#java.util.HashMap {}>
(java.util.HashMap. m) => <#java.util.HashMap {}>
m3 => <#clojure.lang.PersistentArrayMap {}>
(java.util.HashMap. m3) => <#java.util.HashMap {}>
您似乎不需要空的 Clojure 映射作为构造函数 arg,然后问题就消失了。您还可以通过将 *warn-on-reflection*
设置为 false(在 project.clj
中或在代码中手动设置)来使警告消失。
如果你使用类型提示,很容易在错误的地方得到它,它会被默默地忽略。
更新
考虑这个额外的代码:
(dotest
(newline)
(set! *warn-on-reflection* false) ; not executed upon parsing
(let [m4 ^java.util.Map {}]
(spyxx (new java.util.HashMap m4)) ; Reflection Warning
(spyxx (java.util.HashMap. m4)))) ; Reflection Warning
(newline)
; vvv executed when parsed before following lines
(set! *warn-on-reflection* false)
(let [m5 ^java.util.Map {}]
(spyxx (new java.util.HashMap m5)) ; Works
(spyxx (java.util.HashMap. m5))) ; Works
第一个测试在解析时生成反射警告(测试之前是 运行),因为解析器似乎正在计算常量表达式(推测)。
第二个测试不会生成警告,因为 Clojure 正在依次读取、解析和评估每个表单。因此调用 (set! *warn-on-reflection* false)
在读取和评估以下行之前执行以禁用警告。
您需要在构造函数参数中添加一个提示:
(let [^java.util.Map m {}]
(new java.util.HashMap m))