Pattern matching in Kotlin is nice and the fact it does not execute the next pattern match is good in 90% of use cases.
In Android, when database is updated, we use Java switch property to go on next case if we do not put a break to have code looking like that:
switch (oldVersion) { case 1: upgradeFromV1(); case 2: upgradeFromV2(); case 3: upgradeFromV3(); }
So if someone has an app with version 1 of the DB and missed the app version with DB v2, he will get all the needed upgrade code executed.
Converted to Kotlin, we get a mess like:
when (oldVersion) { 1 -> { upgradeFromV1() upgradeFromV2() upgradeFromV3() } 2 -> { upgradeFromV2() upgradeFromV3() } 3 -> { upgradeFromV3() } }
Here we have only 3 versions, imagine when DB reaches version 19.
Anyway to makes when acting in the same way then switch? I tried to continue without luck.
Kotlin has a simple and concise syntax. Codes written in this language have better readability than equivalent codes written in Java. Below are three different ways to write a simple function that adds two numbers together. The first 2 examples are written in Kotlin, while the third is written in Java.
A switch statement is usually more efficient than a set of nested ifs. Deciding whether to use if-then-else statements or a switch statement is based on readability and the expression that the statement is testing.
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.
Kotlin language allows lesser errors and prevents common programming mistakes which saves a lot of time of developers debugging. The fewer lines of code undoubtedly increase your productivity and help you to build one or more features at that time of writing the code.
Simple but wordy solution is:
if (oldVersion <= 1) upgradeFromV1() if (oldVersion <= 2) upgradeFromV2() if (oldVersion <= 3) upgradeFromV3()
Another possible solution with function references:
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]() } }
edit: Original response below. Here's what I'm currently doing:
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) }
Here's a variation on the answer @C.A.B. gave:
fun upgrade(oldVersion: Int) { when (oldVersion) { latestVersion -> return 1 -> upgradeFromV1() 2 -> upgradeFromV2() 3 -> upgradeFromV3() } upgrade(oldVersion + 1) }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With