Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Guard when setting multiple class properties in Swift 2

It's trivial enough to do something like this:

class Collection {
    init(json: [String: AnyObject]){
        guard let id = json["id"] as? Int, name = json["name"] as? String else {
            print("Oh noes, bad JSON!")
            return
        }
    }
}

In that case we were using let to initialize local variables. However, modifying it to use class properties causes it to fail:

class Collection {

    let id: Int
    let name: String

    init(json: [String: AnyObject]){
        guard id = json["id"] as? Int, name = json["name"] as? String else {
            print("Oh noes, bad JSON!")
            return
        }
    }

}

It complains that let or var needs to be used but obviously that isn't the case. What's the proper way to do this in Swift 2?

like image 819
Luke Sapan Avatar asked Jul 07 '15 14:07

Luke Sapan


1 Answers

In the if let, you are unwrapping values from the optional as new local variables. You can’t unwrap into existing variables. Instead, you have to unwrap, then assign i.e.

class Collection {

    let id: Int
    let name: String

    init?(json: [String: AnyObject]){
        // alternate type pattern matching syntax you might like to try
        guard case let (id as Int, name as String) = (json["id"],json["name"]) 
        else {
            print("Oh noes, bad JSON!")
            self.id = 0     // must assign to all values
            self.name = ""  // before returning nil
            return nil
        }
        // now, assign those unwrapped values to self
        self.id = id
        self.name = name
    }

}

This is not specific to class properties - you can’t conditionally bind into any variable, for example this doesn’t work:

var i = 0
let s = "1"
if i = Int(s) {  // nope

}

Instead you need to do:

if let j = Int(s) {
  i = j
}

(though of course, in this case you’d be better with let i = Int(s) ?? 0)

like image 174
Airspeed Velocity Avatar answered Oct 13 '22 14:10

Airspeed Velocity