Swift 2引入了guard关键字,它可以用来确保各种数据配置就绪。我在这个网站上看到的一个例子演示了一个submitTapped函数:
func submitTapped() {
guard username.text.characters.count > 0 else {
return
}
print("All good")
}
我想知道使用guard与使用if条件的老式方法是否有任何不同。它是否提供了简单支票无法获得的好处?
Swift 2引入了guard关键字,它可以用来确保各种数据配置就绪。我在这个网站上看到的一个例子演示了一个submitTapped函数:
func submitTapped() {
guard username.text.characters.count > 0 else {
return
}
print("All good")
}
我想知道使用guard与使用if条件的老式方法是否有任何不同。它是否提供了简单支票无法获得的好处?
当前回答
来源:《Swift》中的Guard
让我们看一个例子来清楚地理解它
示例1:
func validate() {
guard 3>2 else {
print ("False")
return
}
print ("True") //True
}
validate()
在上面的例子中,我们看到3大于2,守卫else子句中的语句被跳过并打印True。
示例2:
func validate() {
guard 1>2 else {
print ("False") //False
return
}
print ("True")
}
validate()
在上面的例子中,我们看到1小于2,守卫else子句内的语句被执行,False被打印出来,后面跟着return。
Example 3: gaurd let, unwrapping optionals through guard let
func getName(args myName: String?) {
guard let name = myName, !name.isEmpty else {
print ("Condition is false") // Condition is false return
}
print("Condition is met\(name)")
}
getName(args: "")
在上面的例子中,我们使用保护let来打开可选项。在函数getName中,我们定义了一个可选的字符串类型变量myName。然后使用守卫let检查变量myName是否为nil,如果没有赋值给name,再次检查,name不为空。如果两个条件都是合格的,即true, else块将被跳过并打印“条件符合名称”。
基本上,我们在这里检查两个用逗号分隔的东西,首先是展开和可选,然后检查它是否满足条件。
这里我们没有向函数传递任何东西,即空字符串,因此打印Condition为false。
func getName(args myName: String?) {
guard let name = myName, !name.isEmpty else {
print ("Condition is false")
return
}
print("Condition is met \(name)") // Condition is met Hello
} getName(args: "Hello")
在这里,我们将“Hello”传递给函数,您可以看到输出打印为“Condition is met Hello”。
其他回答
和if语句一样,guard也根据表达式的布尔值执行语句。与if语句不同,guard语句只在条件不满足时运行。您可以将守卫更像Assert,但是可以优雅地退出,而不是崩溃。
请参考: http://ericcerney.com/swift-guard-statement/
当使用守护满足条件时,它将在守护块中声明的变量暴露给代码块的其余部分,将它们带入其作用域。如前所述,这将在嵌套的if let语句中派上用场。
注意,guard在其else语句中要求return或throw。
使用Guard解析JSON
下面是一个如何使用guard而不是if-let解析JSON对象的示例。这是一篇博客文章的节选,其中包括一个playground文件,你可以在这里找到:
如何使用守卫在Swift 2解析JSON
func parseJSONWithGuard(data : [String : AnyObject]) throws -> Developer {
guard let firstname = data["First"] as? String else {
return Developer() // we could return a nil Developer()
}
guard let lastname = data["Last"] as? String else {
throw ParseError.BadName // or we could throw a custom exception and handle the error
}
guard let website = data["WebSite"] as? String else {
throw ParseError.BadName
}
guard let iosDev = data["iosDeveloper"] as? Bool else {
throw ParseError.BadName
}
return Developer(first: firstname, last: lastname, site: website, ios: iosDev)
}
下载操场:守卫操场
更多信息:
以下是Swift编程语言指南的节选:
If the guard statement’s condition is met, code execution continues after the guard statement’s closing brace. Any variables or constants that were assigned values using an optional binding as part of the condition are available for the rest of the code block that the guard statement appears in. If that condition is not met, the code inside the else branch is executed. That branch must transfer control to exit the code block that that guard statement appears in. It can do this with a control transfer statement such as return, break, or continue, or it can call a function or method that doesn’t return, such as fatalError().
来自苹果文档:
保安声明
守卫语句用于在一个或多个条件不满足时将程序控制转移到作用域之外。
Synatx:
guard condition else {
statements
}
优势:
1. 通过使用guard语句,我们可以摆脱深度嵌套的条件,这些条件的唯一目的是验证一组需求。
2. 它是专门为提前退出方法或函数而设计的。
如果你使用If,下面是它看起来的代码。
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
if error == nil {
if let statusCode = (response as? HTTPURLResponse)?.statusCode, statusCode >= 200 && statusCode <= 299 {
if let data = data {
//Process Data Here.
print("Data: \(data)")
} else {
print("No data was returned by the request!")
}
} else {
print("Your request returned a status code other than 2XX!")
}
} else {
print("Error Info: \(error.debugDescription)")
}
}
task.resume()
如果一个或多个条件不满足,可以使用守卫将控制转移到作用域之外。
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
/* GUARD: was there an error? */
guard (error == nil) else {
print("There was an error with your request: \(error)")
return
}
/* GUARD: Did we get a successful 2XX response? */
guard let statusCode = (response as? HTTPURLResponse)?.statusCode, statusCode >= 200 && statusCode <= 299 else {
print("Your request returned a status code other than 2XX!")
return
}
/* GUARD: was there any data returned? */
guard let data = data else {
print("No data was returned by the request!")
return
}
//Process Data Here.
print("Data: \(data)")
}
task.resume()
参考:
1. Swift 2:带着警卫早点离开 2. Udacity 3.保安声明
简单地说,它提供了一种在执行之前验证字段的方法。这是一种很好的编程风格,因为它增强了可读性。在其他语言中,它可能是这样的:
func doSomething() {
if something == nil {
// return, break, throw error, etc.
}
...
}
但是因为Swift为你提供了可选项,我们不能检查它是否为nil并将其值赋值给一个变量。相反,if let检查它不是nil,并分配一个变量来保存实际值。这就是警卫发挥作用的地方。它为您提供了一种更简洁的方式,可以使用可选项提前退出。
阅读这篇文章,我注意到使用Guard的巨大好处
下面你可以用一个例子来比较guard的用法:
这是没有防备的部分:
func fooBinding(x: Int?) {
if let x = x where x > 0 {
// Do stuff with x
x.description
}
// Value requirements not met, do something
}
在这里,您将所需的代码放在所有条件中 您可能不会立即发现这有什么问题,但是您可以想象,如果它嵌套了许多在运行语句之前都需要满足的条件,那么它会变得多么令人困惑
解决这个问题的方法是首先进行每一项检查,如果有任何不符合就退出。这样可以很容易地理解什么条件将使该函数退出。
但是现在我们可以使用guard,我们可以看到它可以解决一些问题:
func fooGuard(x: Int?) {
guard let x = x where x > 0 else {
// Value requirements not met, do something
return
}
// Do stuff with x
x.description
}
检查你想要的条件,而不是你不想要的条件。这同样类似于断言。如果条件不满足, 运行Guard的else语句,跳出函数。 如果条件通过,这里的可选变量将自动在保护的范围内为您展开 语句被调用——在本例中是fooGuard(_:)函数。 您可以尽早检查坏的情况,使您的函数更易于阅读和维护
同样的模式也适用于非可选值:
func fooNonOptionalGood(x: Int) {
guard x > 0 else {
// Value requirements not met, do something
return
}
// Do stuff with x
}
func fooNonOptionalBad(x: Int) {
if x <= 0 {
// Value requirements not met, do something
return
}
// Do stuff with x
}
如果你还有任何问题,你可以阅读整篇文章:Swift guard声明。
结束
最后,通过阅读和测试,我发现如果你使用guard来打开任何可选选项,
这些未包装的值将保留在您的其余部分中使用 代码块
.
guard let unwrappedName = userName else {
return
}
print("Your username is \(unwrappedName)")
在这里,打开的值只在if块中可用
if let unwrappedName = userName {
print("Your username is \(unwrappedName)")
} else {
return
}
// this won't work – unwrappedName doesn't exist here!
print("Your username is \(unwrappedName)")