例如,如示例here中所述,
=> (-> "a b c " .toUpperCase (.replace "A" "X") (.split " ") first)
=> "X"
我希望能够做类似
的事情 => (-> ^String "a b c " .... etc etc
避免反射惩罚,尤其是在与java代码的接口。
答案 0 :(得分:4)
可以使用->
宏键入提示表达式。以下使用反射:
(set! *warn-on-reflection* true)
(def s "1")
(-> s .toString)
;; Reflection warning, NO_SOURCE_PATH:1:1 - reference to field toString can't be resolved.
;;= "1"
这不是:
(-> ^String s .toString)
;;= "1"
也许如果你分享一个特定的表达式,你发现很难或不可能输入提示,我们可以帮助你更好。
有一种已知情况,即丢弃附加到宏的&form
表达式的类型提示,请参阅此JIRA票证Macroexpansion discards &form metadata。也许这就是你所看到的?
答案 1 :(得分:2)
是的,这是可能的。
如果您需要键入提示->
的初始参数,您可以直接在->
表单内部或外部执行此操作:
(-> ^String (foo) .toUpperCase)
(let [^String f (foo)]
(-> f .toUpperCase))
在任何一种情况下都没有反映。
如果您希望键入提示的值出现在->
链的中间步骤,那么您可以通过将类型提示放在->
步骤上来键入提示:
;; note the type hints on identity and (identity)
(-> ^String (foo) .toUpperCase ^String identity .toLowerCase)
(-> ^String (foo) .toUpperCase ^String (identity). toLowerCase)
同样,在任何一种情况下都不会有任何反映。
(测试为1.7.0-alpha5 REPL。)
答案 2 :(得分:1)
嗯,至少在你的情况下,没有反映惩罚。
user=> (set! *warn-on-reflection* true)
true
user=> (-> "a b c " .toUpperCase (.replace "A" "X") (.split " ") first)
"X"
如果你想更加确定:
user=> (def i 23)
#'user/i
user=> (.toString i)
Reflection warning, NO_SOURCE_PATH:1:1 - reference to field toString can't be resolved.
"23"