我不明白,为什么下面的代码会产生一个反射警告:反思警告
(set! *warn-on-reflection* true)
(defmacro my-macro [k] `(.length ~(with-meta k {:tag String})))
(defn my-fun1 [k] (my-macro k))
;; Reflection warning, /tmp/form-init2370243866132870536.clj:1:18 - reference to field length can't be resolved.
使用macroexpand-1
表明,生成的代码确实有typehint,如果我写的一样手动代码不使用宏,没有反射警告:
(set! *print-meta* true)
(macroexpand-1 '(my-macro k))
;; (.length ^java.lang.String k)
(defn my-fun2 [k] (.length ^String k))
;; All good, no reflection warning
标杆函数示出了警告不只是红色鲱鱼,反射实际上发生在运行时:
(time (reduce + (map my-fun1 (repeat 1000000 "test"))))
;; "Elapsed time: 3080.252792 msecs"
(time (reduce + (map my-fun2 (repeat 1000000 "test"))))
;; "Elapsed time: 275.204877 msecs"
当我运行'macroexpand-1'行,我没有看到类型暗示。然而,我认为宏观有问题,它不会接受字符串:'(my-macro“foo”); => java.lang.ClassCastException:java.lang.String不能转换为clojure.lang.IObj'。 – Mars
你应该看到类型提示。你确定你把'* print-meta *'设置为true吗? – noziar