https://kotlinlang.org logo
#getting-started
Title
# getting-started
x

xii

08/24/2021, 7:34 PM
and also, i've upgraded for kotlin 1.3 to 1.4 and noticed some smart casts to string have broken; is doing toString in the original object sufficient, or does smart cast do something I'm not taking into account?
c

corneil

08/24/2021, 8:42 PM
How about an example of the failing code?
x

xii

08/25/2021, 8:12 AM
of course:
Copy code
data class Test(
  val otherValue: Instant
  val nullableMap: Map<String,String>? = null
)

class TestClass(){
  fun previouslyFineFunction(foo: Test){
    val body = mutableMapOf(
      "otherValue" to foo.otherValue
    )
    if (foo.nullableMap != null){
       body["baz"] = foo.nullableMap
    }
  }
}
previously the
Copy code
body["baz"] = foo.nullableMap
worked straight up
k

Klitos Kyriacou

08/25/2021, 8:18 AM
Isn't the right-hand side of that assignment supposed to be an Instant?
x

xii

08/25/2021, 8:21 AM
no, it's a mutable map of <String, Any>
previously, my IDE would say
Copy code
Smart cast to kotlin.collections.Map<kotlin.String, kotlin.String>
on the body["baz"] line
but now it doesnt do it by itself
k

Klitos Kyriacou

08/25/2021, 8:36 AM
Yes, it still smart-casts
foo.nullableMap
to
Map<kotlin.String, kotlin.String>
since it knows it's not null. But that's not where the problem is. You can't put a Map as a value into a Map that was initialized with an Instant as a value. If you really want to do that, you have to be explicit about its type when you create it:
Copy code
val body : Map<String, Any> = mutableMapOf(...)
x

xii

08/25/2021, 8:45 AM
hmmm
the error i get from 1.4 forwards is
Copy code
Type mismatch.
Required:
Comparable<{Instant & String}>
Found:
Map<String, String>
Type mismatch.
Required:
Serializable
Found:
Map<String, String>
Type mismatch.
Required:
{Comparable{Instant & String}> & java.io.Serializable}
Found:
Map<String, String>
but you are right in that if I specify <String, Any> it behaves as it used to
k

Klitos Kyriacou

08/25/2021, 9:08 AM
The inferred type of
body
depends on the contents of the
MutableMap
that you initialize it with. For the compiler to give the above error message, you must have initialized it with:
Copy code
val body = mutableMapOf(
            "otherValue" to foo.otherValue,
            "xyz" to "abc",
        )
and not just with
"otherValue" to foo.otherValue
. The inferred type it chooses is the most restrictive type that matches all of the arguments to
mutableMapOf
. If you gave it another type, which was totally different from these two, then it would have to infer the map type as
Map<String, Any>
. For example, if you did this:
Copy code
val body = mutableMapOf(
            "otherValue" to foo.otherValue,
            "xyz" to listOf(123)
        )
then your code would work.
👍 1
x

xii

08/25/2021, 9:11 AM
yep, very interesting! thank you! 🙂
2 Views