Swift's switch next to Kotlin's when
Working mostly on iOS means re-remembering how to write Kotlin's when every time, so here the two are side by side.
- Published
- Updated
This article is also published elsewhere. https://iganin.hatenablog.com/entry/2019/08/14/210620
Originally written in Japanese. This is a translation of the same piece.
Introduction
Besides if/else, branching in Swift uses switch and in Kotlin when. I work on iOS most of the time,
so writing a Kotlin when always costs me a moment of remembering how it goes — hence this comparison,
partly as a way of learning it properly.
Environment
I used the following, both web playgrounds:
- Swift - http://online.swiftplayground.run/
- Kotlin - https://play.kotlinlang.org
The comparison
In Kotlin’s when, you write when (value) followed by condition -> expression for what happens in each
branch. The default case — when none of the listed conditions match — is written with else. Another
distinguishing feature is that in Kotlin a when expression can be assigned to a variable.
enum class SampleValue {
a,
b,
c,
d
}
fun main() {
var string = "sample"
when (string) {
"sample" -> {
println("this is sample")
}
"hoge" -> {
println("this is hoge")
}
"huga" -> {
println("this is huga")
}
else -> {
println("other")
}
}
val constant = when (string) {
"sample" -> "sample"
else -> "others"
}
val sampleValue = SampleValue.a
when (sampleValue) {
SampleValue.a, SampleValue.b -> println("a or b")
SampleValue.c -> println("c")
SampleValue.d -> println("d")
}
}
In Swift’s switch, you write switch value followed by case condition: expression. The default case —
again, when nothing else matches — is written as default: expression. Unlike Kotlin, you cannot assign a
switch directly to a variable in Swift. To do something similar you have to assign it as the return value
of a closure.
import Foundation
let sample = "sample"
let a: String = {
switch sample {
case "sample": return "sample"
default: return "other"
}
}()
switch sample {
case "sample": print("this is sample")
case "hoge": print("this is hoge")
case "huga": print("this is huga")
default: print("this is other")
}
enum Value: Int {
case a = 0
case b
case c
case d
}
let valueSample: Value = .a
switch valueSample {
case .a, .b: print("a or b")
case .c: print("c")
case .d: print("d")
}
Addendum, 29 August
Adding this after some advice on Twitter. Kotlin’s when apparently gets smart casts.
Concretely, in code like the following, when a branch runs on a type match such as is Int, x has already
been cast to Int by the time you are inside the expression — so no cast is needed and you can treat it as
an Int.
when (x) {
is Int -> Do Something (x is already recognised as Int here, so x + 1 = 2)
is String -> Do Something (recognised as String here, so x + 1 prints something like 11)
else -> Do Something
}
[Kotlin every day] Day 9. Smart casts | DevelopersIO (Japanese)