“何时”语句与Java“切换”语句

Kotlin中的模式匹配很好,不会执行下一个模式匹配的事实在90%的用例中是好的。

在Android中,当数据库被更新的时候,如果我们不打算让代码看起来像这样,我们使用Java switch属性继续下一个案例:

switch (oldVersion) { case 1: upgradeFromV1(); case 2: upgradeFromV2(); case 3: upgradeFromV3(); } 

因此,如果某人有一个应用程序版本1的数据库,并与数据库版本2错过了应用程序版本,他会得到所有必要的升级代码执行。

转换到科特林,我们得到一个混乱像:

 when (oldVersion) { 1 -> { upgradeFromV1() upgradeFromV2() upgradeFromV3() } 2 -> { upgradeFromV2() upgradeFromV3() } 3 -> { upgradeFromV3() } } 

这里我们只有3个版本,想象一下当DB达到版本19时:/

无论如何,当以相同的方式进行行动而不是开关? 我试着继续没有运气。

简单但罗嗦的解决方案是:

 if (oldVersion <= 1) upgradeFromV1() if (oldVersion <= 2) upgradeFromV2() if (oldVersion <= 3) upgradeFromV3() 

另一个可能的解决方案是函数引用

 fun upgradeFromV0() {} fun upgradeFromV1() {} fun upgradeFromV2() {} fun upgradeFromV3() {} val upgrades = arrayOf(::upgradeFromV0, ::upgradeFromV1, ::upgradeFromV2, ::upgradeFromV3) fun upgradeFrom(oldVersion: Int) { for (i in oldVersion..upgrades.lastIndex) { upgrades[i]() } } 

编辑:下面的原始回应。 这是我目前正在做的事情:

 fun upgrade() { fun upgradeFromV1() { /* Do stuff */ } fun upgradeFromV3() { /* Do stuff */ } tailrec fun upgradeFrom(version: Int): Unit = when (version) { LATEST_VERSION -> { Config.version = version } 1 -> { upgradeFromV1() upgradeFrom(2) } in 2..3 -> { upgradeFromV3() upgradeFrom(4) } else -> { Log("Uncaught upgrade from $version") upgradeFrom(version+1) } upgradeFrom(Config.version) } 

以下是@CAB给出的答案的变体:

 fun upgrade(oldVersion: Int) { when (oldVersion) { latestVersion -> return 1 -> upgradeFromV1() 2 -> upgradeFromV2() 3 -> upgradeFromV3() } upgrade(oldVersion + 1) } 

这个怎么样:

 fun upgradeFromV3() {/* some code */} fun upgradeFromV2() {/* some code */ upgradeFromV3()} fun upgradeFromV1() {/* some code */ upgradeFromV2()} fun upgradeFromV0() {/* some code */ upgradeFromV1()} fun upgrade(oldVersion: Int) { when (oldVersion) { 1 -> upgradeFromV1() 2 -> upgradeFromV2() 3 -> upgradeFromV3() } } 

这里是来自bashor的两个答案的组合,带有一点功能性糖:

 fun upgradeFromV0() {} fun upgradeFromV1() {} fun upgradeFromV2() {} fun upgradeFromV3() {} val upgrades = arrayOf(::upgradeFromV0, ::upgradeFromV1, ::upgradeFromV2, ::upgradeFromV3) fun upgradeFrom(oldVersion: Int) { upgrades.filterIndexed { index, kFunction0 -> oldVersion <= index } .forEach { it() } } 

OP的另一个答案是:

 override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { when (oldVersion) { newVersion -> return 1 -> TODO("upgrade from v1") 2 -> TODO("upgrade from v2") } onUpgrade(db, oldVersion,newVersion) } 

这是绝对可能的引用https://kotlinlang.org/docs/reference/control-flow.html

 If many cases should be handled in the same way, the branch conditions may be combined with a comma: when (x) { 0, 1 -> print("x == 0 or x == 1") else -> print("otherwise") } 

因此,如果相同的条件列表很短,那么您可以列出他们分开彗星,或使用范围,如1..10条件如其他答案中所述

 val orders = arrayListOf( { upgradeFromV1()}, { upgradeFromV2()}, { upgradeFromV3()} ) orders.drop(oldVersion).forEach { it() }