6
votes

Is there a way in Swift to assign conditional expressions similar to this

let foo = if (bar == 2) {
        100
    } else {
        120
    }

(or with a switch case).

(Don't want to have to use ternary operator for this).

This kind of assignement is good for functional style / immutability. The expressions have a return value in this case.

Note: it's a general question, this is just simplified example, imagine e.g. a switch case with a lot of values, pattern matching, etc. You can't do that with ternary operator.

Btw also note that there are languages that don't support ternary operator because if else returns a value, so it's not necessary, see e.g. Scala.

1
‘Don't want to have to use ternary operator for this’ What?! Why? - Biffen
Because ternary operator can become quickly unreadable and is rather unflexible (compared to switch case at least). - User
why not: let foo = (bar == 2) ? 100 : 120? - holex
@lxx That comment made me cry. The answer to the question is a ternary operator. - Biffen
This is a clear question and yes the ternary operator is not the answer for many/most cases. - WestCoastProjects

1 Answers

17
votes

You can use a closure to initialize an immutable:

let foo: Int = {
    if bar == 2 {
        return 100
    } else {
        return 120
    }
}()

The advantage of using a closure is that it's a function, so you can use any complex logic inside, implemented in a clean way and not through nested ternary operators. It can be a switch statement, it can be obtained as the return value of a function followed by some calculations, it can be a pattern matching case, it can be a combination of them all, etc.

Said in other words, it's the same as initializing with the return value of a function, but the difference is that the function is inline and not somewhere else, with readability benefits.

Just for completeness, if the variable is mutable, you can use deferred initialization:

var foo: Int

// Any statement here

if bar == 2 {
    foo = 100
} else {
    foo = 120
}

// Other statements here

myFunc(foo)

so you can declare a mutable variable, and initialize it anywhere in the same scope, but before using it the variable must be initialized.

Update: Since Swift 2.0, deferred initialization also works with immutables.