Security when setting up multiple class properties in Swift 2

This is 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 this case, we used let to initialize local variables. However, changing it to use the properties of the class fails:

 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 } } } 

He complains that let or var should be used, but obviously this is not the case. What is the correct way to do this in Swift 2?

+5
source share
1 answer

In if let you expand the values ​​from optional as new local variables. You cannot expand existing variables. Instead you need to unzip, then assign ie

 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 does not apply to class properties - you cannot conditionally bind to any variable, for example, this does not work:

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

Instead, you need to do:

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

(although, of course, in this case you are better off with let i = Int(s) ?? 0 )

+12
source

All Articles