Daniel Talks Code

View Original

Use .run to init objects and perform calculations in one go

Continuing our journey through the world of Kotlin Scope Functions we now have .run, which comes in two delicious flavors: as an extension function on the provided object, or as a non-extension function.

As an Extension Function

This allows us to create an object and use it to compute tasks within the corresponding lambda. You’re given the context object as a receiver (meaning you use the keyword “this” to access the object and its members) and the returned value is the result of the expressions in the lambda.

class TimeMachine(
    val type: String,
    var fuel: String,
    var destinationYear: Int,
) {
    fun changeFuelType(newFuel: String) {
        fuel = newFuel
    }

    fun changeDestinationYear(year: Int) {
        destinationYear = year
    }
}

fun main() {

    fun timeTravel(timeMachine: TimeMachine, traveler: String): String {
        return "$traveler traveled to ${timeMachine.destinationYear} on the ${timeMachine.type} using ${timeMachine.fuel}"
    }

    val adventure = TimeMachine(
        "DeLorean",
        "plutonium",
        1955,
    ).run {
        changeFuelType("⚡️")
        changeDestinationYear(1985)
        timeTravel(this, "Marty McFly")
    }

    println(adventure)
    // Marty McFly traveled to 1985 on the DeLorean using ⚡️
}

As a Non-Extension Function

You can also use .run as a non-extension function to perform several calculations at once and store the result in a variable. Neat and tidy 😎.

// Average age of the cast when making the first film

val averageAge = run {

    val cast = mapOf(
        "Michael J. Fox" to 28,
        "Lea Thompson" to 24,
        "Christopher Lloyd" to 47,
        "Crispin Glover" to 21,
        "Thomas F. Wilson" to 26,
        "Claudia Wells" to 19,
        "Wendie Jo Sperber" to 27,
    )

    cast.values.average().toInt()
}

println(averageAge)
See this content in the original post