The following code produces two reflection warnings (for .getBytes
):
(defn make-it-a-string-please [x]
(str x))
(defn test1 [x]
(-> x
(cond-> (int? x) make-it-a-string-please)
(.getBytes)))
(defn test2 [x]
(-> x
(make-it-a-string-please)
(.getBytes)))
I can type hint test2
:
(defn test2 [x]
(-> x
^String (make-it-a-string-please)
(.getBytes)))
Now the reflection warning is gone. But a similar type hint in test1
doesn’t work:
(defn test1 [x]
(-> x
^String (cond-> (int? x) make-it-a-string-please)
(.getBytes)))
Is it possible to type hint this without modifying make-it-a-string-please
and without extracting the cond->
part to a var (to type hint it there)?
2
You should consider both branches of the cond
expression.
- When
(int? x)
is true, the result of(make-it-a-string-please x)
will be called, which can be type hinted directly on the function definition:
(defn make-it-a-string-please ^String [x]
(str x))
- Else, the value of
x
will be used, but we have no information about its type either. You can type hint it as well.
(defn test1 [x]
(-> ^String x
(cond-> (int? x) make-it-a-string-please)
(.getBytes)))
(Please note, type hinting does not enforce the type, it only helps the compiler to prevent reflection calls.)
Alternatively, you can just add a redundant toString convertion (which does nothing because x
is already a String) before the .getBytes
call:
(defn test1 [x]
(-> x
(cond-> (int? x) make-it-a-string-please)
(str)
(.getBytes)))
2