观察以下 repl 会话:
user=> (set! *warn-on-reflection* true)
true
user=> (defn blah [s] (for [c s] (if (Character/isDigit c) true false)))
Reflection warning, NO_SOURCE_PATH:1:31 - call to isDigit can't be resolved.
Reflection warning, NO_SOURCE_PATH:1:31 - call to isDigit can't be resolved.
#'user/blah
user=> (blah "abc123abc")
(false false false true true true false false false)
user=> (defn blah [s] (for [^char c s] (if (Character/isDigit c) true false)))
#'user/blah
user=> (blah "abc123abc")
(false false false true true true false false false)
所以我们使用了一个类型提示^char
来摆脱反射——太好了。现在在函数参数中尝试同样的事情:
user=> (defn blah-c [c] (if (Character/isDigit c) true false))
Reflection warning, NO_SOURCE_PATH:1:22 - call to isDigit can't be resolved.
#'user/blah-c
user=> (defn blah-c [^char c] (if (Character/isDigit c) true false))
CompilerException java.lang.IllegalArgumentException: Only long and double primitives are supported, compiling:(NO_SOURCE_PATH:1:1)
user=> (defn blah-c [^Character c] (if (Character/isDigit c) true false))
#'user/blah-c
user=> (blah-c \1)
true
user=> (blah-c \a)
false
我了解 Clojure仅支持数字原语的长或双精度类型提示,并且 Javachar
是数字数据类型 - 无需解释。但上面似乎不一致的类型提示^char
在第一个函数中是允许的for
,但不是在函数签名中blah-c
,我必须在其中指定Character
。这是什么原因(即从编译器实现的角度来看)?