I'm scratching my head here a bit regarding extens...
# getting-started
m
I'm scratching my head here a bit regarding extension functions. Can someone explain to me why this works
Copy code
private fun <String> HashMap<String, String>.myExt(key: String, incomingValue: String) {
    this[key] = incomingValue
}
But not this
Copy code
private fun <String> HashMap<String, String>.myExt(key: String, incomingValue: String) {
    this[key] = "something else"
}
The latter gives me (in IntelliJ):
Copy code
Type mismatch.
Required: String#1 (type parameter of myExt)
Found: kotlin.String
j
Interestingly,
this[key] = "something else" as String
fixes the compiler error?
Ah it changes it to a warning about an unchecked cast. Somehow the type of the value in the Map is inferred to be
String#1
? Seems like a bug
m
Exactly, was just going to write that. So you think it's a bug? I was assuming that I'm missing something
j
Ah no, wait! It should be
Copy code
fun HashMap<String, String>.myExt(key: String, incomingValue: String) {
    this[key] = "something else"
}
The initial
<String>
makes no sense here
Hold on, does it somehow use
String
as a generic type parameter instead of
kotlin.String
?
m
Of course! Thank you very much πŸ™‚ It was autogenerated but that makes sense.
j
You're welcome πŸ™‚
m
Regarding
String
vs
kotlin.String
I don't know really
m
the
String
in the original function is just a name you have given to the generic parameter, it has nothing to do with
kotlin.String
. You could replace it with
Abcd
(or more often used
T
) and the function would work exactly same
βž• 1
m
Now that you mention it, it's very clear πŸ˜ƒ thank you! πŸ˜ƒ
πŸ‘‹ 1
j
It surprises me that that is even allowed, the potential for confusion is profound πŸ˜€
πŸ˜… 1
m
how would you prevent it tho? Ban all possible classnames?
m
Yeah I thought about that too, would be kind of tricky tro draw a line there
n
this is a pretty funny issue πŸ™‚ I dunno about banning classnames, but any generic parameter that's not a single character should catch your eye. (I don't love that convention but it's the convention...)
m
I saw code using type parameters longer than a letter, always adopted the Uppercase convention, to avoid confusion. Example:
Message<REQUEST, RESPONSE>
or in Assertj:
interface Assert<SELF extends Assert<SELF, ACTUAL>, ACTUAL> ...