Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the advantages/use cases of optional patterns introduced in swift 2?

For the simple cases like if let or guard I don't see the advantage,

if case let x? = someOptional where ... {
  ...
}

//I don't see the advantage over the original if let

if let x = someOptional where ... {
  ...
}

For the for-case-let case to simplify working with optional collections, I really hope swift can go one step further:

for case let x? in optionalArray {
  ...
}

//Wouldn't it be better if we could just write

for let x? in optionalArray {
  ...
}

After google it for a while the only case I find useful is this "Swift 2 Pattern Matching: Unwrapping Multiple Optionals" :

switch (username, password) {
case let (username?, password?):
    print("Success!")
case let (username?, nil):
    print("Password is missing")
...

So any other advantages of introducing optional patterns?

like image 658
Qiulang 邱朗 Avatar asked Apr 27 '16 04:04

Qiulang 邱朗


People also ask

Why optionals are useful in Swift?

An optional value allows us to write clean code with at the same time taking care of possible nil values. If you're new to Swift you might need to get used to the syntax of adding a question mark to properties. Once you get used to them you can actually start benefiting from them with, for example, extensions.

How are optional implemented in Swift?

How are optionals implemented in Swift. We have already noted that an optional is a wrapper that can wrap an instance of a given Swift type. This is implemented using a generic enum as follows. The enum has two cases, to represent the absence and presence of a wrapped instance respectively.

What are optionals in Swift?

Swift also introduces optional types, which handle the absence of a value. Optionals say either “there is a value, and it equals x” or “there isn't a value at all”. Using optionals is similar to using nil with pointers in Objective-C, but they work for any type, not just classes.

What is optional binding in Swift example?

Optional binding is a mechanism built into Swift to safely unwrap optionals. Since an optional may or may not contain a value, optional binding always has to be conditional. To enable this, conditional statements in Swift support optional binding, which checks if a wrapped value actually exists.


1 Answers

I believe you're conflating two different concepts. Admittedly, the syntax isn't immediately intuitive, but I hope their uses are clarified below. (I recommend reading the page about Patterns in The Swift Programming Language.)

case conditions

The "case condition" refers to the ability to write:

  • if case «pattern» = «expr» { ... }
  • while case «pattern» = «expr» { ... }
  • for case «pattern» in «expr» { ... }

These are particularly useful because they let you extract enum values without using switch.

Your example, if case let x? = someOptional ..., is a valid example of this, however I believe it's most useful for enums besides Optional.

enum MyEnum {
    case A
    case B(Int)
    case C(String)
}

func extractStringsFrom(values: [MyEnum]) -> String {
    var result = ""

    // Without case conditions, we have to use a switch
    for value in values {
        switch value {
        case let .C(str):
            result += str
        default:
            break
        }
    }

    // With a case condition, it's much simpler:
    for case let .C(str) in values {
        result += str
    }

    return result
}

You can actually use case conditions with pretty much any pattern that you might normally use in a switch. It can be weird sometimes:

  • if case let str as String = value { ... } (equivalent to if let str = value as? String)
  • if case is String = value { ... } (equivalent to if value is String)
  • if case 1...3 = value { ... } (equivalent to if (1...3).contains(value) or if 1...3 ~= value)

The optional pattern, a.k.a. let x?

The optional pattern, on the other hand, is a pattern that lets you unwrap optionals in contexts besides a simple if let. It's particularly useful when used in a switch (similar to your username/password example):

func doSomething(value: Int?) {
    switch value {
    //case 2:  // Not allowed
    case 2?:
        print("found two")

    case nil:
        print("found nil")

    case let x:
        print("found a different number: \(x)")
    }
}
like image 57
jtbandes Avatar answered Sep 29 '22 07:09

jtbandes