https://kotlinlang.org logo
Title
m

mickeelm

12/12/2020, 11:54 AM
I'm scratching my head here a bit regarding extension functions. Can someone explain to me why this works
private fun <String> HashMap<String, String>.myExt(key: String, incomingValue: String) {
    this[key] = incomingValue
}
But not this
private fun <String> HashMap<String, String>.myExt(key: String, incomingValue: String) {
    this[key] = "something else"
}
The latter gives me (in IntelliJ):
Type mismatch.
Required: String#1 (type parameter of myExt)
Found: kotlin.String
j

Joris PZ

12/12/2020, 11:58 AM
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

mickeelm

12/12/2020, 12:03 PM
Exactly, was just going to write that. So you think it's a bug? I was assuming that I'm missing something
j

Joris PZ

12/12/2020, 12:04 PM
Ah no, wait! It should be
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

mickeelm

12/12/2020, 12:05 PM
Of course! Thank you very much 🙂 It was autogenerated but that makes sense.
j

Joris PZ

12/12/2020, 12:05 PM
You're welcome 🙂
m

mickeelm

12/12/2020, 12:05 PM
Regarding
String
vs
kotlin.String
I don't know really
m

Milan Hruban

12/12/2020, 1:27 PM
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

mickeelm

12/12/2020, 1:31 PM
Now that you mention it, it's very clear 😃 thank you! 😃
👋 1
j

Joris PZ

12/12/2020, 2:15 PM
It surprises me that that is even allowed, the potential for confusion is profound 😀
😅 1
m

Milan Hruban

12/12/2020, 2:31 PM
how would you prevent it tho? Ban all possible classnames?
m

mickeelm

12/12/2020, 2:32 PM
Yeah I thought about that too, would be kind of tricky tro draw a line there
n

nanodeath

12/13/2020, 5:44 PM
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

Matteo Mirk

12/14/2020, 11:31 AM
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> ...