Kotlin:访问when语句的参数

问题描述 投票:0回答:4

有没有办法获取我传递到

when
语句中的表达式的值?

在我的应用程序中,我有一个像这样的

KeyListener

_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)
    }
})

Kotlin 有简洁的语法来访问

e?.keyCode
吗?我真的不想重复这个表达。

syntax kotlin
4个回答
45
投票

Kotlin 1.3 支持捕获变量中

when
的主题表达式。这是语法:

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

原答案

几天前我自己也遇到了这个问题。我认为如果能够在

it
表达式中访问
when
的值就好了。

我通过将表达式分配给

val
表达式之前的
when
来解决这个问题:

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

不幸的是,这需要您添加额外的大括号和线条。但好处是,

e?.keyCode
只会被评估一次。在这种情况下,这可能并不重要,但如果表达式更大,这种方法将是合适的。

编辑:

另一种可能性是将

when
表达式包装在对
let
的调用中。它允许您使用
it
访问参数。像这样:

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

5
投票

从 Kotlin 1.1 开始这是不可能的。此功能有一个开放的功能请求:https://youtrack.jetbrains.com/issue/KT-4895


4
投票

您可以尝试以下操作,即使它稍微改变了语义。我想,就你的情况来说,可能没问题。

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

2
投票

在 Kotlin 1.3 中,您可以将参数设置为作用域变量并访问它。

_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)
    }
})
© www.soinside.com 2019 - 2024. All rights reserved.