我如何知道哪个监护人声明失败了? [英] How do I tell which guard statement failed?

查看:93
本文介绍了我如何知道哪个监护人声明失败了?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一堆链接在一起的警卫队让命语句,那么如何在不将我的警卫队让分为多个语句的情况下诊断出哪种情况失败了?

If I’ve got a bunch of chained guard let statements, how can I diagnose which condition failed, short of breaking apart my guard let into multiple statements?

给出以下示例:

guard let keypath = dictionary["field"] as? String,
    let rule = dictionary["rule"] as? String,
    let comparator = FormFieldDisplayRuleComparator(rawValue: rule),
    let value = dictionary["value"]
    else
    {
        return nil
    }

我怎么知道4个let语句中哪个是失败的并调用了else块?

How can I tell which of the 4 let statements was the one that failed and invoked the else block?

我能想到的最简单的方法是将语句分解为4个顺序的警卫语句,但这感觉不对。

The simplest thing I can think of is to break out the statements into 4 sequential guard else statements, but that feels wrong.

 guard let keypath = dictionary["field"] as? String
    else
    {
        print("Keypath failed to load.")

        self.init()
        return nil
    }

    guard let rule = dictionary["rule"] as? String else
    {
        print("Rule failed to load.")

        self.init()
        return nil
    }

    guard let comparator = FormFieldDisplayRuleComparator(rawValue: rule) else
    {
        print("Comparator failed to load for rawValue: \(rule)")

        self.init()
        return nil
    }

    guard let value = dictionary["value"] else
    {
        print("Value failed to load.")

        self.init()
        return nil
    }

如果我想将它们全部保留在一个警卫声明中,可以考虑另一种选择。检查guard语句中的nil可能有用:

If I wanted to keep them all in one guard statement, I can think of another option. Checking for nils inside the guard statement might work:

guard let keypath = dictionary["field"] as? String,
    let rule = dictionary["rule"] as? String,
    let comparator = FormFieldDisplayRuleComparator(rawValue: rule),
    let value = dictionary["value"]
    else
    {

        if let keypath = keypath {} else {
           print("Keypath failed to load.")
        }

        // ... Repeat for each let...
        return nil
    }

我什至不知道它是否可以编译,但是我可能以及一堆 if let 语句或 guard 开头。

I don't even know if that will compile, but then I might as well have used a bunch of if let statements or guards to begin with.

Swift的惯用方式是什么?

What's the idiomatic Swift way?

推荐答案

Erica Sadun刚刚写道

Erica Sadun just wrote a good blog post on this exact topic.

她的解决方案是劫持 where 子句并使用它跟踪哪些防护声明通过。使用 diagnose 方法的每个成功的警卫条件都会将文件名和行号打印到控制台。最后一个诊断打印语句后的保护条件是失败的。解决方案如下所示:

Her solution was to hi-jack the where clause and use it to keep track of which guard statements pass. Each successful guard condition using the diagnose method will print the file name and the line number to the console. The guard condition following the last diagnose print statement is the one that failed. The solution looked like this:

func diagnose(file: String = #file, line: Int = #line) -> Bool {
    print("Testing \(file):\(line)")
    return true
}

// ...

let dictionary: [String : AnyObject] = [
    "one" : "one"
    "two" : "two"
    "three" : 3
]

guard
    // This line will print the file and line number
    let one = dictionary["one"] as? String where diagnose(),
    // This line will print the file and line number
    let two = dictionary["two"] as? String where diagnose(),
    // This line will NOT be printed. So it is the one that failed.
    let three = dictionary["three"] as? String where diagnose()
    else {
        // ...
}

埃里卡(Erica)关于该主题的文章可以在此处

Erica's write-up on this topic can be found here

这篇关于我如何知道哪个监护人声明失败了?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆