Kotlin vs Swift: Elvis vs If-Let & Guard
Tags: Android App Development, Programming, Swift, Kotlin, iOS App Development

Learning Kotlin and Swift

Kotlin vs Swift: Elvis vs If-Let & Guard

Explore Kotlin and Swift together and learn their differences

Image by traveLink from Pixabay

One of the most distinct different one can clearly see between Kotlin and Swift code is the initial checking condition of Swift code. You’ll notice in Swift code, there are guard and if-let .

In Kotlin, there’s no guard or if-let . What it has is Elvis Operator ?: (imagine Elvis head rotated left 90 degrees, and you’ll see his hair and two eyes 😎 ).

But how are they comparable? Let me tell you the story…

But before that…

One thing we need to be fully aware of is, in both Kotlin and Swift, it’s a modern language that helps you eliminate the null reference crash. They are done using Nullable type vs Optional type, which looks the same, but different somehow. Check out the detail below.

Both Elvis, If-Let and Guard, are there to aid the null checking condition.

Conventional style

In the days of Java and ObjC, one can also check for null to safeguard the code execution down the road.

In Swift, we can do something as

// Swift

func doSomething(a: String?) {

if a == nil {

return

}

print(a!.count)

}

Note we have to use a! to force unwrap a using the ! . Such code looks not neat.

In Kotlin, we can do something similar

// Kotlin

fun doSomething(a: String?) {

if (a == null) {

return

}

println(a.length)

}

Notice we don’t need a! as the a as Kotlin after the a == null check, it knows a won’t be null, and auto-cast to a non-nullable type. Hence looks okay.

The if-let comes into play

Given in Swift, the need to force unwrap if we just use a normal if to check for it. Swift introduces a combination of if let , where it will try to unwrap the optional variable.

// Swift

func doSomething(a: String?) {

if let unwrapA = a {

print(unwrapA.count)

}

}

This looks much neater, as we eliminate the need of ! . The reason is we only unwrap a to unwrapA if it is not null. After that, we can use unwrap it as a non-optional variable.

But there’s one limitation is, the unwrapA can only be used within the if scope. (there are some benefits of constraining the unwrapA within the scope only through)

In Kotlin, the previous example of

// Kotlin

fun doSomething(a: String?) {

if (a == null) {

return

}

println(a.length)

}

is still relatively nice, as the a is not constraint and can use anywhere within doSomething function.

However if in Kotlin, if wanted to do something similar to if let of Swift, one can use the let scope function as below

// Kotlin

fun doSomething(a: String?) {

a?.let {

println(it.length)

}

}

The let scope function will take a and convert it to it (or any other name if one prefers) if it is not null. And the it is only within the scope of the let function.

In case you like to know scope functions better, check out the below article.

The guard comes into play

In Swift, given the limitation of if let that only unwrap the variable within the if scope, the guard come in handy to help.

// Swift

func doSomething(a: String?) {

guard let unwrapA = a else {

return

}

print(unwrapA.count)

}

Now the guard basically, overturn the if else checking situation, where if a is not null, it will unwrap into unwrapA and can be used anywhere within the doSomething function.

This looks really neat.

Compare to Kotlin’s version, they look pretty identical now.

// Kotlin

fun doSomething(a: String?) {

if (a == null) {

return

}

println(a.length)

}

Where is Elvis ?? … or rather ?:

Ops, sorry… did I forgot about Elvis.

Here he comes. In Kotlin, the conventional way of checking as shown above can be further shortened to below (eliminating the {} and put the return in the same line as if condition)

// Kotlin

fun doSomething(a: String?) {

if (a == null) return

println(a.length)

}

But we can do another further neat trick using Elvis Operator, i.e. ?:

// Kotlin

fun doSomething(a: String?) {

a ?: return

println(a.length)

}

Using Elvis, it does

check if a is null, then it exits the function

is null, then it exits the function auto-cast a to non-nullable if it is not null.

In Swift, if we try to use nil coalescing i.e. ?? , it will error out, and it can’t do anything as below.

// Swift

func doSomething(a: String?) {

a ?? return // Error: expect an expression after ??

print(a.count) // Error: a is still optional

}

So the best we can do is as below

// Swift

func doSomething(a: String?) {

guard let unwrapA = a else { return }

print(unwrapA.count0

}

The below article shares on Kotlin’s side how one gets to the Elvis Operator consideration.

But guard can handle more than one variable!

In Swift, the guard can be used to check on multiple variables.

// Swift

func doSomething(a: String?, b: String?) {

guard let aa = a, let bb = b else { return }

print(aa.count + bb.count)

}

True. That’s one of the benefits of guard .

In Kotlin, with Elvis, we can try as below, to imitate it

// Kotlin

fun doSomething(a: String?, b: String?) {

a ?: return; b ?: return

println(a.length + b.length)

}

For mutable variable of Kotlin, auto-cast will not work. Check out below for how to handle that.

But guard can handle non-optional variable checks

In Swift, other than unwrapping optional variable, the guard can also use to check normal boolean as shown below.

func doSomething(a: String?) {

guard let aa = a, aa != "" else { return }

print(aa.count)

}

In such case, the Kotlin Elvis gave up… let’s get back to the normal faithful if checks

fun doSomething(a: String?) {

if (a == null || a == "") return

println(a.length)

}