What's New in Swift 2: repeat-while, guard, defer, ErrorType, OptionSetType, multi-payload enums, if-case, for-case, #available, try!


Here I grab some of the main details from the WWDC 2015: What's new in Swift talk (with Chris Latter and John McCall), expanding each one into workable code that can be cut and pasted into a playground.

repeat-while

The do keyword is replaced by repeat in the do-while context:
var i = 0
repeat {
    print("Hello World!")
    i++
}
while i < 10

guard

Using if-let often you need to do a lot of work within the scope of the braces that follow the statement or pass a value back to another optional. With guard you deal with the else statement first for what happens if the statement fails, after which you have access to the value(s) in non-optional form.
func optionalInt() -> Int? {
    return 10
}

func guardFunc() {
guard let c = optionalInt() else {
    return
}
print(c)
}


guardFunc()

defer

The defer keyword enables us to do something when code within the current scope completes.
func optionalInt() -> Int? {
    return 10
}

func guardFunc() {
defer { print("guardFunc() ended") }
guard let c = optionalInt() else {
    return
}
print(c)
}

guardFunc()
In the WWDC video defer is used in the context of delegates, but it can be used for any purpose and means that even if a method completes with an error instead of returning a value, the defer code still gets called.
enum OptionalError:ErrorType {
    case ExceededInt32Max
}

func optionalInt() -> Int? {
    return nil
}

func guardFunc() throws {
    defer { print("guardFunc() ended") } // "guardFunc() ended"
    guard let c = optionalInt() else {
        throw OptionalError.ExceededInt32Max
    }
    print(c)
}

do {
try guardFunc()
}
catch {
}

ErrorType

In the above example, I use the ErrorType along with throw and catch syntax. (Note: associated with throw and catch is the rethrows syntax.)

OptionSetType

This is the new layout used to create option sets given in the WWDC video:
struct Options:OptionSetType {
    let rawValue: Int
    static let One = Options(rawValue: 1)
    static let Two = Options(rawValue: 2)
    static let Three = Options(rawValue: 3)
    
}

Multi-payload enums

Whereas before enums could only have one type, now they can have multiple types, and a generic example was shown:
enum Either<T1,T2> {
    case First(T1)
    case Second(T2)
}

let a:Either<String,Int> = .First("String")

if-case

The use of if-case enables you to avoid building switch statements when you don't want the bulk of them. 
if case .First(let value) = a {
print(value)
}

for-case

Following the syntax used in the WWDC video, this should work:
enum MyEnum {
    case Food(String)
}

let enumValues = [MyEnum.Food("Burger")]

for case .Food(let value) in enumValues {
        print(value)
}
It doesn't at present, but this does:
enum MyEnum {
    case Food(String)
}

let enumValues = [MyEnum.Food("Burger")]

for case let .Food(value) in enumValues {
    print(value) // Burger
}
Note how the position of the let has shifted (thanks to Al Skipp's code for identifying that this is possible) and actually the let can also be shifted in the if-case instance and still works (although it is not the order identified in Apple's documentation):
if case let .First(value) = a {
    print(value)
}

#available

We can now contextually use code based on OS versions without any awkward workarounds:
func optionalInt() -> Int? {
    if #available(iOS 9, *) {
        return nil
    }
    return 1
}

try! (impossible errors)

Using try with an exclamation mark is shorthand for forcing an assertion and have the program end if an error is thrown, rather than catch the error.
enum NumberError:ErrorType {
    case ExceededInt32Max
}
func doOrDie(callback:(Int) throws -> Int) {
    try! callback(Int(Int32.max)+1)
}
doOrDie({v in if v <= Int(Int32.max) { return v }; throw NumberError.ExceededInt32Max})

What else?

There's plenty more covered in the video: recursive enums (coming soon), improved testing, rich comments (using Markdown), protocol extensions, methodification. I highly recommend watching this one, because it just features so much. While I've caught some of it in this net, it's worth seeing for yourself too.

Stefan Lesser (Swift Evangelist)

Finally we are invited, alongside bug reporting and forum use, to contact Stefan Lesser directly if we need to: slesser@apple.com.


Endorse on Coderwall

Comments