5

I understand how "!" or "?" works. But i'm not quite sure what the added benefit is compared to != nil checking. What is the added benefit of moving to "!?"? I feel like it's just something Apple has added but can't really see the extra benefit compared to status quo of iOS. Am i missing something here? Thanks in advance.

shle2821
  • 1,856
  • 1
  • 19
  • 26
  • 2
    Why should I check for nil every time I use a variable when I can declare it as not-optional and can be sure that it will never be nil? – Matthias Bauch Mar 13 '15 at 16:04
  • It is more a convenient feature to write shorter and more readable code. It is not typical to Swift but also available in other languages like Groovy. – Arne Burmeister Mar 13 '15 at 16:44

2 Answers2

5

The ? operator is very convenient, when it comes to chaining, e.g.:

a?.b?.c?.doSomething()

Otherwise you would have to check a, b and c for nil, which may result in more unreadable code than chaining does.

Another thing is, that you can easily mark arguments being optional, e.g.

func someFunc(arg: Type?)

and it is immediately clear, that this is a type which may be nil, i.e. the language enforces this. Otherwise you would pass something which could be nil and you forget the check and experience crashes.

Sebastian
  • 8,046
  • 2
  • 34
  • 58
5

The difference between checking for nil and requiring an optional being unwrapped can amount to the difference between your code crashing or not. Optionals, when used correctly, can both increase safety and make your code more readable.

Suppose you have an array, and you want to get out the first value in it. You might do it like this:

if !arr.isEmpty {
    useValue(arr[0])
}

But of course, it’s easy to forget that isEmpty part, and if you do, your code will crash with an out-of-bounds error.

So intead, there’s a much better way: use the array's first method, which returns an optional with nil if the array is empty:

if let val = arr.first {
    useValue(val)
}

With this form, you cannot get this wrong. It’s impossible to use the arr. first value without unwrapping it. If you forget, you get a compilation error. It’s also more readable to my eyes/

Presumably you would expect your != nil formulation to work something like this:

if arr.first != nil {
    // all optionals would be “implicit”
    useValue(arr.first)
}

Putting aside that you’re calling .first twice which is a bit inefficient, and the question of type compatibility, essentially this lands you back to square one – you could forget to do the nil comparison, and then, kaboom. Or, you could take the Objective-C approach and say nil is fine to send messages to – but that also leads to all kinds of confusion (personally I hate the idea of an implicit sending messages to nil meaning no-op), and also leads to the question, what do you do when the function returns a value type such as an Int. Must everything be nullable? This leads to much mess in Obj-C land.

What’s more, there are all sorts of conveniences you can introduce once you are dealing with optionals, such as nil-coalescing:

// default to 0 if no first element
arr.first ?? 0
// much neater than this equivalent form:
arr.first != nil ? arr.first : 0

or optional comparison:

// will only be true if arr is non-nil and zero
if arr.first == 0 {

}

For more examples, see this answer

Community
  • 1
  • 1
Airspeed Velocity
  • 40,491
  • 8
  • 113
  • 118
  • Perhaps something you didn't know on the null coalescing: It's not much different in objective-c. The "true" parameter can be missed to form a slightly different syntax null coalescing operator. e.g. `id element = array[0] ?: defaultValue;` – James Webster May 26 '15 at 23:14
  • Why can't you just write `id first = arr.first; if (first != nil) { ... }` in Objective-C ? Then it won't be calling first twice. When you release software, you test to ensure it doesn't crash during development, if it does, you fix it during development. By the time you reach release stage, your code is rather confident without a bunch of `if let var = something {...}` littering your methods, making your objective c methods nice and short. – Zhang Jul 22 '16 at 03:12