swift - 在 Swift 2 中设置多个类属性时的守卫

标签 swift swift2 guard-statement

做这样的事情很简单:

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 中执行此操作的正确方法是什么?

最佳答案

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
    }

}

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

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

}

相反,您需要这样做:

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

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

关于swift - 在 Swift 2 中设置多个类属性时的守卫,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31271241/

相关文章:

xcode - 第二个窗口简单显示 : OS X & Swift

swift - 在 Swift 中更改 UIProgressView 的高度

swift2 - 如何在函数之外使用 guard ?

ios - Swift:通过能够在 defer 语句中捕获返回值来简化调试

Swift 2.0 守卫给我错误

ios - 如何使用 CloudKit 通过 CKQueryOperation 迭代查询直到游标为零?

swift - 我怎样才能 "blindly inject"具有任意值的对象变量?

ios - UIScrollView 的 contentOffset 在添加小数字时被截断

ios - Swift 2 - 可视化用于调试的 AVMutableComposition : Converting Apple's AVCompositionDebugViewer

swift - 从 NSData 到 Swift 2 中的 SecKeyRef