kotlintype-conversion

How Int converts to the String?


I have a code like this:

fun main() {
    val users = listOf(
        User("Tom", 32),
        User("Kirill", 44),
        User("Anton",51)
    )
    val stringUsers = conversation(users)
        println(it)
    }
}
fun conversation(users: List<User>):List<String> {
val string = mutableListOf<String>()
for (user in users)
    string.add("Name: ${user.name}, Age: ${user.age}")
    return string
    }

And i dont understand, why "age" of User converts to String. IMO to convert it - i need to use something like ".toString()", am I?


Solution

  • Short answer: There is a hidden call to toString() as you expect, but it's added by the compiler.

    Long answer:

    The relevant line in the code is this one:

    string.add("Name: ${user.name}, Age: ${user.age}")

    This is called a string interpolation, where you mix a string with variables to form a single final string. Now if we refer to this other question: How does string interpolation work in Kotlin?. There the accepted answer says that string interpolation is actually converted to a StringBuilder instance by compiler magic. So your line, when compiled, ends up being something like this:

    string.add(new StringBuilder().append("Name: ").append(user.name).append(", Age: ").append(user.age).toString())
    

    Note that now your number gets feed into the append method of the StringBuilder, still as a number. Now, if we refer to the official documentation of that function: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/-string-builder/append.html

    You'll see that there is an overload that takes an Int as a parameter, that's the one you're calling here. Looking at the documentation it has this to say:

    Appends the string representation of the specified int value to this string builder and returns this instance. The overall effect is exactly as if the value were converted to a string by the value.toString() method, and then that string was appended to this string builder.

    And there is the call to toString() you expected. Well hidden behind compiler tricks and within the internal implementation of standard objects. That's the reason why you passed an Int and ended up with a string, there is a conversion.