Home > Software engineering >  Return Type: Calling a function inside Vs outside `println()`
Return Type: Calling a function inside Vs outside `println()`

Time:12-30

I'm new to Kotlin.

I was experimenting with Anonymous functions a little bit until facing different outputs for the same concept using different approaches.

  • First: Creating my Anonymous function:
var greetingFunction = { playerName: String , numBuildings: Int ->
    val currentYear = 2022
    println("Adding $numBuildings houses")
    "Welcome to SimVillage, $playerName! (Copyright $currentYear)\n"
}
  • Second: Creating a function that takes another function as a parameter:
private fun runSimulation(playerName: String, greetingFunc: (String, Int) -> String){
    val numOfBuildings = (1..3).shuffled().last()
    println(greetingFunc(playerName, numOfBuildings))
}

A- Regular call for Anonymous function:

println(runSimulation("Ahmed", greetingFunction))

Output:

Adding 3 houses
Welcome to SimVillage, Ahmed! (Copyright 2022)

B- Shorthand call for Anonymous function:

println(runSimulation("Different") { playerName: String , numBuildings: Int ->
    val currentYear = 2022
    println("Adding $numBuildings houses")
    "Welcome to SimVillage, $playerName! (Copyright $currentYear)\n"
})

Output:

Adding 2 houses
Welcome to SimVillage, Different! (Copyright 2022)

kotlin.Unit

I tried to remove the println() and calling the runSimulation function directly and the output was:

Output:

Adding 2 houses
Welcome to SimVillage, Different! (Copyright 2022)

What I really want to know is: how in the first place did I get that "kotlin.Unit" print using the Shorthand Syntax?

CodePudding user response:

Kotlin will automatically infer the type of lambda expressions. Since the last line of greetingFunction is a String

var greetingFunction = { playerName: String , numBuildings: Int ->
    val currentYear = 2022
    println("Adding $numBuildings houses")

    // the last line is a string -> Kotlin will infer that the return type is a String
    "Welcome to SimVillage, $playerName! (Copyright $currentYear)\n"
}

the inferred type is

var greetingFunction: (String, String) -> String

Return types for block-body functions are not inferred. If a function does not return a useful value, its return type is Unit. The function

private fun runSimulation(playerName: String, greetingFunc: (String, Int) -> String) {
    val numOfBuildings = (1..3).shuffled().last()
    println(greetingFunc(playerName, numOfBuildings))
}

will therefore return Unit, so

println(runSimulation("foo") { _, _ -> "bar" })

will print the returned value of runSimulation(), and Unit.toString() is kotlin.Unit

Since runSimulation() will also print to stdout, this is effectively the same as running

println(println("bar"))

First the 'inner' println() will output bar, and then the 'outer' println() will print kotlin.Unit.

bar
kotlin.Unit
  • Related