Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin: Accessing parameter of when-statement

Tags:

syntax

kotlin

Is there a way to get the value of the expression I passed into the when statement?

In my application I have a KeyListener like that

_content.addKeyListener(object : KeyAdapter() {
    override fun keyPressed(e: KeyEvent?) = when(e?.keyCode) {
        KeyEvent.VK_T -> mainWindow.enterTrainingState()
        KeyEvent.VK_P -> mainWindow.enterPlayState()
        KeyEvent.VK_E -> mainWindow.close()
        else -> println(e?.keyCode)
    }
})

Has Kotlin a neat syntax to access e?.keyCode? I don't really want to repeat the expression.

like image 829
danielspaniol Avatar asked Feb 01 '17 12:02

danielspaniol


People also ask

When condition check in Kotlin?

Kotlin has the following conditionals: Use if to specify a block of code to be executed, if a specified condition is true. Use else to specify a block of code to be executed, if the same condition is false. Use else if to specify a new condition to test, if the first condition is false.

When without argument Kotlin?

2.6. when{} Used Without an Argument. Kotlin allows us to omit the argument value in the when block. This essentially turns when into a simple if-elseif expression that sequentially checks cases and runs the block of code of the first matching case.

When case in Kotlin?

Android Dependency Injection using Dagger with Kotlin Kotlin does not provide an option to write a switch-case statement; however we can implement the switch-case functionality in Kotlin using the when() function which works exactly the same way switch works in other programming languages.


2 Answers

I had this problem myself a couple of days ago. I think it would have been nice to be able to access the value as it inside the when-expression.

I solved it by assigning the expression to a val before the when expression:

val keyCode = e?.keyCode
when(keyCode) {
    KeyEvent.VK_T -> mainWindow.enterTrainingState()
    KeyEvent.VK_P -> mainWindow.enterPlayState()
    KeyEvent.VK_E -> mainWindow.close()
    else -> println(keyCode)
}

Unfortunately, this would require you to add extra braces and lines. The upside though, is that e?.keyCode would only be evaluated once. It may not matter in this exact case, but if the expression was bigger, this approach would be suitable.

Edit:

Another possibility it to wrap the when expression in a call to let. It lets you access the parameter with it. Like this:

e?.keyCode.let {
    when(it) {
        KeyEvent.VK_T -> mainWindow.enterTrainingState()
        KeyEvent.VK_P -> mainWindow.enterPlayState()
        KeyEvent.VK_E -> mainWindow.close()
        else -> println(it)
  }
}

Edit2:

Kotlin 1.3 has support for capturing the subject expression of a when in a variable. This is the syntax:

when(val keyCode = e?.keyCode) {
    KeyEvent.VK_T -> mainWindow.enterTrainingState()
    KeyEvent.VK_P -> mainWindow.enterPlayState()
    KeyEvent.VK_E -> mainWindow.close()
    else -> println(keyCode)
}
like image 110
marstran Avatar answered Oct 14 '22 10:10

marstran


With Kotlin 1.3, you can set the parameter as a scoped variable and access it.

_content.addKeyListener(object : KeyAdapter() {
    override fun keyPressed(e: KeyEvent?) = when(val keycode = e?.keyCode) {
        KeyEvent.VK_T -> mainWindow.enterTrainingState()
        KeyEvent.VK_P -> mainWindow.enterPlayState()
        KeyEvent.VK_E -> mainWindow.close()
        else -> println(keycode)
    }
})
like image 44
Huy T Avatar answered Oct 14 '22 08:10

Huy T