在Swift

时间:2016-05-05 12:19:09

标签: swift

我们不能对先前声明的变量使用可选绑定吗?现在能够做到if letguard似乎很自然。我想的是:

var jsonData:AnyObject?

if jsonData = try? NSJSONSerialization.JSONObjectWithData(data, options: []) {
    //use jsonData! safely
}
//still be able to use jsonData?

或者

var jsonData:AnyObject?

guard jsonData = try? NSJSONSerialization.JSONObjectWithData(data, options: []) else {
    print("Could not parse JSON")
}
//still use jsonData?

为什么范围有限?为什么不让我们在任何地方使用变量?

我想要做的是在分配/解包一个可选(和执行条件代码)时避免两个单独的语句,这似乎是if letguard的最初目的。 :

var jsonData: AnyObject?

jsonData = try? NSJSONSerialization.JSONObjectWithData(data, options: [])
if(jsonData != nil) {
    //use jsonData! safely
}
//still use jsonData?

是否有一种很酷的方法可以解决这个问题,或者是使用两种语句的唯一选择?

编辑

再次查看代码,我看到我在这个场景中的主要用途是在分配/解包某些重要的可选变量而没有重要的流程重定向时尝试print()消息。我的实际代码中的关键语句是:

jsonData = try? NSJSONSerialization.JSONObjectWithData(data, options: [])
if(jsonData == nil) {
    print("Could not parse data")
}

我的印象是,if letguard完全是为了合并这两个陈述,但我觉得这并不是他们的意图。 。我希望我在Code Review中更清楚地解释了我的问题。

3 个答案:

答案 0 :(得分:1)

guard letguard没有let仅评估布尔表达式

guard let jsonData = try? NSJSONSerialization.JSONObjectWithData(data, options: []) else {
    print("Could not parse JSON")
}
// use jsonData

答案 1 :(得分:1)

// use jsonData! safely

在这种情况下,绝不应该使用!if let的重点是避免!的危险。但是对于你的问题,做这个IMO的最好方法是:

let jsonData = try? NSJSONSerialization.JSONObjectWithData(data, options: [])
if let jsonData = jsonData {
    // use jsonData as itself
}

// use jsonData? as optional

尽管如此,我很少遇到这种情况,它可能表明代码处理不当。在任何情况下,都不清楚在这里删除一行是值得进一步使语言复杂化的,但如果你有一个令人信服的用例以这种方式改变Swift,那就是Swift-Evolution过程是为了。

答案 2 :(得分:0)

据我所知,它的工作方式与你想要的一样。在游乐场中尝试以下操作以查看结果。 myData语句中使用的print名称表现为具有不同范围的不同变量。

func indefinite() throws -> AnyObject? {
    return "asd"
    //return nil
}

var myData: AnyObject?

if let myData = try indefinite() {
    print("Unwrapped \(myData.dynamicType)")
} else {
    print("Optional \(myData.dynamicType)")
}

如果我正在编写真正的代码,我可能会使用...

if let safeData = try indefinite() {
    print("Unwrapped \(safeData.dynamicType)")

...来代替。