我如何知道哪个监护人声明失败了? [英] How do I tell which guard statement failed?
问题描述
如果我有一堆链接在一起的警卫队让命语句,那么如何在不将我的警卫队让分为多个语句的情况下诊断出哪种情况失败了?
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 guard
s 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屋!