Swift Guard Statement

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swift Guard Statement相关的知识,希望对你有一定的参考价值。

When the first saw the Swift guard statement during Apple’s Platform State of the Union, I couldn’t quite understand why I would ever use it. So what is it?

Like an if statement, guard executes statements based on a Boolean value of an expression. Unlike an if statement, guard statements only run if the conditions are not met. You can think of guard more like an Assert, but rather than crashing, you can gracefully exit.

Even after seeing some examples, I only saw it as a confusing way to accomplish what we already could with Optional Binding or with if-else statements alone.

Diving In

Let’s take a simple example comparing current techniques vs using the new guard statement:

1 func fooManualCheck(x: Int?) {
2     if x == nil || x <= 0 {
3         // Value requirements not met, do something
4         return
5     }
6     
7     // Do stuff with x
8     x!.description
9 }

This is the most basic Objective-C style way to make sure a value exists and that it meets a condition. Now this works fine, but has a couple flaws:

  1. You’re checking for a condition that you don’t want, rather than checking for the value you do want. Code becomes confusing when you have a bunch of checks like this. What you’re hoping for here is that your condition actually doesn’t pass.
  2. You also need to force unwrap the optional value after the condition fails.

Swift gave us a way to clean this up and fix some of these flaws through Optional Binding:

1 func fooBinding(x: Int?) {
2     if let x = x where x > 0 {
3         // Do stuff with x
4         x.description
5     }
6     
7     // Value requirements not met, do something
8 }

This removes both of the flaws that the first function had, but adds a new one. Here you’re putting your desired code within all the conditions, rather than afterward. You might not immediately see a problem with this, but you could imagine how confusing it could become if it was nested with numerous conditions that all needed to be met before running your statements.

The way to clean this up is to do each of your checks first, and exit if any aren’t met. This allows easy understanding of what conditions will make this function exit.

I’ve heard this called the Bouncer Pattern, which makes a lot of sense. You want to get rid of the bad cases before they get in the door. It also allows you to think about one case at a time, rather than figuring out how all combinations need to work together.

Here enters the guard statement:

1 func fooGuard(x: Int?) {
2     guard let x = x where x > 0 else {
3         // Value requirements not met, do something
4         return
5     }
6     
7     // Do stuff with x
8     x.description
9 }

Using guard solves all 3 of the issues mentioned above:

  1. Checking for the condition you do want, not the one you don’t. This again is similar to an assert. If the condition is not met, guard‘s else statement is run, which breaks out of the function.
  2. If the condition passes, the optional variable here is automatically unwrapped for you within the scope that the guard statement was called – in this case, the fooGuard(_:) function. This is an important, yet notably strange feature that really makes the guard statement useful.
  3. You are checking for bad cases early, making your function more readable and easier to maintain.

The cool thing is that this same pattern holds true for non-optional values as well:

 1 func fooNonOptionalGood(x: Int) {
 2     guard x > 0 else {
 3         // Value requirements not met, do something
 4         return
 5     }
 6     
 7     // Do stuff with x
 8 }
 9  
10 func fooNonOptionalBad(x: Int) {
11     if x <= 0 {
12         // Value requirements not met, do something
13         return
14     }
15     
16     // Do stuff with x
17 }

Wrapping Up

This simple example shows how you could start using guard immediately in your Swift code to make your function/methods more clear. It’s easy for us to immediately judge the value of a new feature until you give it a chance and see what it can or can’t do for you.

Going from Objective-C to Swift is a huge change, not only to syntax, but how you have to look at architecting your code. You can only benefit from this awesome new language if you actively change your mindset while writing code by expanding your everyday patterns and style.

Reference:Swift Guard Statement

Reference:Swift的Guard语句

以上是关于Swift Guard Statement的主要内容,如果未能解决你的问题,请参考以下文章

Swift - guard关键字(守护)

Swift Guard Statement

Swift的Guard语句

Swift的Guard语句

swift中 if let 与 guard let 对比,guard会降低一个分支

swift 来自https://thatthinginswift.com/guard-statement-swift/