遵守以下REPL會話:^char類型提示不允許的Clojure DEFN參數
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的only supports long or double type hints for numeric primitives,和一個Java char
是數字數據類型 - 不需要解釋。但上面看起來不一致 - 在for
內的第一個函數中允許使用^char
類型的提示,但不在blah-c
的函數簽名中,在那裏我必須指定Character
。這是什麼原因(即從編譯器實現的角度來看)?
組合爆炸 - 對於動態編譯,必須存在每個允許的基元和對象組合的接口。 –
這聽起來像是一個了不起的答案,如果你想擴大它,提供參考/例子。 – noahlz
@noahlz cf. [clojure.lang.IFn](https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/IFn.java) – kotarak