【问题标题】:Guard when setting multiple class properties in Swift 2在 Swift 2 中设置多个类属性时的防护
【发布时间】:2015-07-07 14:20:42
【问题描述】:

做这样的事情很简单:

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

在那种情况下,我们使用let 来初始化局部变量。但是,修改它以使用类属性会导致它失败:

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

}

它抱怨需要使用letvar,但显然情况并非如此。在 Swift 2 中执行此操作的正确方法是什么?

【问题讨论】:

    标签: swift swift2 guard-statement


    【解决方案1】:

    if let 中,您将可选项中的值解包为新的局部变量。您不能将 解包到 现有变量中。相反,您必须打开包装,然后分配即

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

    这不是特定于类属性的——你不能有条件地将绑定到任何变量,例如这不起作用:

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

    相反,您需要这样做:

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

    (当然,在这种情况下,您最好使用let i = Int(s) ?? 0

    【讨论】:

    • 是的,这就是我在此期间所做的,但我认为必须有一种更清洁的方式。谢谢。
    • 不管怎样,不带警卫——请参阅big list,看看是否有另一种解包技术可能适用于这种情况。
    猜你喜欢
    • 1970-01-01
    • 2020-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多