Kotlin: Statement to Lambda

2020-04-01 06:25发布

问题:

How can I make a Kotlin statement to lambda?

I know that you can do that:

fun foo() : () -> Unit {
    return { println("Hello World") }
}

//more beautiful:
fun foo() : () -> Unit = { println("Hello World") }

Is it also possible to create an anonymous lambda without the curly brackets {...}?

In particular in a switch statement, the usual way with curly brackets doesn't look good.

fun bar(i: Int) : () -> Unit {

    return when (i) {

        0 -> { { println("Hello") } }

        1 -> { { println("World") } }

        else -> { { println("Bye") } }
    }
}

Looking forward to your response!

回答1:

Curly braces are the syntax for a lambda expression, you can't create one without them.

In a when statement, you can either give your branch a block body, and return the lambda as its last expression, or you can have a single expression branch return a lambda by wrapping it in parentheses (otherwise it would be interpreted as a branch that executes the code inside the braces):

when (x) {
    "block body returning an Int" -> {
        // do stuff
        25
    }
    "block body returning a lambda" -> {
        // do stuff
        { println("Hello") }
    }
    "single expression returning an Int" -> 25
    "single expression returning a lambda" -> ({ println("Hello") })
}


回答2:

If you like neither {{ nor ({ from zsmb13's answer, you can make it look slightly nicer by defining a rather trivial function:

fun <A> lambda(x: A) = x

// usage
return when (i) {
    0 -> lambda { println("Hello") }
    1 -> lambda { println("World") }
    else -> lambda { println("Bye") }
}


回答3:

This is without curly braces and looking better.

fun getDayType(day: String): String {
return  when (day) {
        "SATURDAY" -> "Half Day"
        "SUNDAY" -> "Holyday"
        else -> "running day"
    }
}


回答4:

When when is used as an expression, a value must be returned, If it is used as an expression, the value of the satisfied branch becomes the value of the overall expression (Just like with if, each branch can be a block, and its value is the value of the last expression in the block.), if you look at the grammar of the when-expression, it can be seen that is made up by when-entries whose right part is in turn formed by controlStructerBodies and these are compounded by blocks, so when you use only a pair of curly braces {} Kotlin recognizes it as a block whose return value is the last expression inside the block, so for this one to be a lambda, a second pair of curly braces is required.

Returns a lambda because is the last and only expression inside the block:

    fun returnLambda(choice: Boolean): ()-> String {
        return when (choice) {
            true ->  {{"Hello"}}
            false -> {{"World"}}
        }

    }

Returns a String because is the last and only expression inside the block:

fun returnString(choice: Boolean): String{
    return when(choice){
        true -> {"Hello"}
        false -> {"world"}
    }
}

This way you can execute different expressions and return a value within the same block:

fun returnString(choice: Boolean): String {
    return when (choice) {
        true -> {
            println("Hello")
            println("world")
            "Hello"
        }
        false -> {
            "world"
        }
    }
}


标签: lambda kotlin