Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 'if let' statement equivalent in Kotlin

Tags:

kotlin

People also ask

What is let in Kotlin?

let takes the object it is invoked upon as the parameter and returns the result of the lambda expression. Kotlin let is a scoping function wherein the variables declared inside the expression cannot be used outside.

What is difference between let and also in Kotlin?

As the name says, also expressions does some additional processing on the object it was invoked. Unlike let, it returns the original object instead of any new return data. Hence the return data has always the same type. Like let , also uses it too.


You can use the let-function like this:

val a = b?.let {
    // If b is not null.
} ?: run {
    // If b is null.
}

Note that you need to call the run function only if you need a block of code. You can remove the run-block if you only have a oneliner after the elvis-operator (?:).

Be aware that the run block will be evaluated either if b is null, or if the let-block evaluates to null.

Because of this, you usually want just an if expression.

val a = if (b == null) {
    // ...
} else {
    // ...
}

In this case, the else-block will only be evaluated if b is not null.


Let's first ensure we understand the semantics of the provided Swift idiom:

if let a = <expr> {
     // then-block
}
else {
     // else-block
}

It means this: "if the <expr> results in a non-nil optional, enter the then-block with the symbol a bound to the unwrapped value. Otherwise enter the else block.

Especially note that a is bound only within the then-block. In Kotlin you can easily get this by calling

<expr>?.also { a ->
    // then-block
}

and you can add an else-block like this:

<expr>?.also { a ->
    // then-block
} ?: run {
    // else-block
}

This results in the same semantics as the Swift idiom.


My answer is totally a copy cat from the others. However, I cannot understand their expression easily. So I guess it would be nice to provide an more understandable answer.

In swift:

if let a = b.val {
  //use "a" as unwrapped
}
else {

}

In Kotlin:

b.val?.let{a -> 
  //use "a" as unwrapped
} ?: run{
  //else case
}

if let statement.

Swift's Optional Binding (so called if-let statement) is used to find out whether an optional contains a value, and if so, to make that value available as a temporary constant or variable. So, an Optional Binding for the if-let statement is as follows:

Swift's if-let statement:

let b: Int? = 50

if let a: Int = b {
    print("Good news!")
} else {
    print("Equal to 'nil' or not set")
}

/*  RESULT: Good news!  */

In Kotlin, like in Swift, to avoid crashes caused by trying to access a null value when it’s not expected, a specific syntax (like b.let { } in second example) is provided for properly unwrapping nullable types:

Kotlin equivalent 1 of Swift's if-let statement:

val b: Int? = null
val a = b

if (a != null) { 
    println("Good news!")
} else { 
    println("Equal to 'null' or not set")
}

/*  RESULT: Equal to 'null' or not set  */

Kotlin’s let function, when used in combination with the safe-call operator ?:, provides a concise way to handle nullable expressions.

Kotlin equivalent 2 (Inline let function and Elvis Operator) of Swift's if-let statement:

val b: Int? = null

val a = b.let { nonNullable -> nonNullable } ?: "Equal to 'null' or not set"
println(a)

/*  RESULT: Equal to 'null' or not set  */


guard let statement.

guard-let statement in Swift is simple and powerful. It checks for some condition and if it evaluates to be false, then the else statement executes which normally will exit a method.

Let's explore a Swift's guard-let statement:

let b: Int? = nil

func method() {
    guard let a: Int = b else {
        print("Equal to 'nil' or not set")
        return
    }
    print("Good news!")
}
method()

/*  RESULT: Equal to 'nil' or not set  */

Kotlin's similar effect of Swift's guard-let statement:

Unlike Swift, in Kotlin, there is no guard statement at all. However, you can use the Elvis Operator?: for getting a similar effect.

val b: Int? = 50

fun method() {
    val a = b ?: return println("Equal to 'null' or not set")
    return println("Good news!")
}
method()

/*  RESULT: Good news!  */

Unlike Swift, Its not necessary to unwrap the optional before using it in Kotlin. We could just check if the value is non null and the compiler tracks the information about the check you performed and allows to use it as unwrapped.

In Swift:

if let a = b.val {
  //use "a" as unwrapped
} else {

}

In Kotlin:

if b.val != null {
  //use "b.val" as unwrapped
} else {

}

Refer Documentation: (null-safety) for more such use cases