| Flow control statements: for, if, else, switch and defer |
| Learn how to control the flow of your code with conditionals, loops, switches and defers. |
| |
| The Go Authors |
| https://golang.org |
| |
| * For |
| |
| Go has only one looping construct, the `for` loop. |
| |
| The basic `for` loop has three components separated by semicolons: |
| |
| - the init statement: executed before the first iteration |
| - the condition expression: evaluated before every iteration |
| - the post statement: executed at the end of every iteration |
| |
| The init statement will often be a short variable declaration, and the |
| variables declared there are visible only in the scope of the `for` |
| statement. |
| |
| The loop will stop iterating once the boolean condition evaluates to `false`. |
| |
| *Note:* Unlike other languages like C, Java, or JavaScript there are no parentheses |
| surrounding the three components of the `for` statement and the braces `{`}` are |
| always required. |
| |
| .play flowcontrol/for.go |
| |
| * For continued |
| |
| The init and post statements are optional. |
| |
| .play flowcontrol/for-continued.go |
| |
| * For is Go's "while" |
| |
| At that point you can drop the semicolons: C's `while` is spelled `for` in Go. |
| |
| .play flowcontrol/for-is-gos-while.go |
| |
| * Forever |
| |
| If you omit the loop condition it loops forever, so an infinite loop is compactly expressed. |
| |
| .play flowcontrol/forever.go |
| |
| * If |
| |
| Go's `if` statements are like its `for` loops; the expression need not be |
| surrounded by parentheses `(`)` but the braces `{`}` are required. |
| |
| .play flowcontrol/if.go |
| |
| * If with a short statement |
| |
| Like `for`, the `if` statement can start with a short statement to execute before the condition. |
| |
| Variables declared by the statement are only in scope until the end of the `if`. |
| |
| (Try using `v` in the last `return` statement.) |
| |
| .play flowcontrol/if-with-a-short-statement.go |
| |
| * If and else |
| |
| Variables declared inside an `if` short statement are also available inside any |
| of the `else` blocks. |
| |
| (Both calls to `pow` return their results before the call to `fmt.Println` |
| in `main` begins.) |
| |
| .play flowcontrol/if-and-else.go |
| |
| * Exercise: Loops and Functions |
| |
| As a way to play with functions and loops, let's implement a square root function: given a number x, we want to find the number z for which z² is most nearly x. |
| |
| Computers typically compute the square root of x using a loop. |
| Starting with some guess z, we can adjust z based on how close z² is to x, |
| producing a better guess: |
| |
| z -= (z*z - x) / (2*z) |
| |
| Repeating this adjustment makes the guess better and better |
| until we reach an answer that is as close to the actual square root as can be. |
| |
| Implement this in the `func`Sqrt` provided. |
| A decent starting guess for z is 1, no matter what the input. |
| To begin with, repeat the calculation 10 times and print each z along the way. |
| See how close you get to the answer for various values of x (1, 2, 3, ...) |
| and how quickly the guess improves. |
| |
| Hint: To declare and initialize a floating point value, |
| give it floating point syntax or use a conversion: |
| |
| z := 1.0 |
| z := float64(1) |
| |
| Next, change the loop condition to stop once the value has stopped |
| changing (or only changes by a very small amount). |
| See if that's more or fewer than 10 iterations. |
| Try other initial guesses for z, like x, or x/2. |
| How close are your function's results to the [[/pkg/math/#Sqrt][math.Sqrt]] in the standard library? |
| |
| (*Note:* If you are interested in the details of the algorithm, the z² − x above |
| is how far away z² is from where it needs to be (x), and the division by 2z is the derivative |
| of z², to scale how much we adjust z by how quickly z² is changing. |
| This general approach is called [[https://en.wikipedia.org/wiki/Newton%27s_method][Newton's method]]. |
| It works well for many functions but especially well for square root.) |
| |
| .play flowcontrol/exercise-loops-and-functions.go |
| |
| * Switch |
| |
| A `switch` statement is a shorter way to write a sequence of `if`-`else` statements. |
| It runs the first case whose value is equal to the condition expression. |
| |
| Go's switch is like the one in C, C++, Java, JavaScript, and PHP, |
| except that Go only runs the selected case, not all the cases that follow. |
| In effect, the `break` statement that is needed at the end of each case in those |
| languages is provided automatically in Go. |
| Another important difference is that Go's switch cases need not |
| be constants, and the values involved need not be integers. |
| |
| .play flowcontrol/switch.go |
| |
| * Switch evaluation order |
| |
| Switch cases evaluate cases from top to bottom, stopping when a case succeeds. |
| |
| (For example, |
| |
| switch i { |
| case 0: |
| case f(): |
| } |
| |
| does not call `f` if `i==0`.) |
| |
| #appengine: *Note:* Time in the Go playground always appears to start at |
| #appengine: 2009-11-10 23:00:00 UTC, a value whose significance is left as an |
| #appengine: exercise for the reader. |
| |
| .play flowcontrol/switch-evaluation-order.go |
| |
| * Switch with no condition |
| |
| Switch without a condition is the same as `switch`true`. |
| |
| This construct can be a clean way to write long if-then-else chains. |
| |
| .play flowcontrol/switch-with-no-condition.go |
| |
| * Defer |
| |
| A defer statement defers the execution of a function until the surrounding |
| function returns. |
| |
| The deferred call's arguments are evaluated immediately, but the function call |
| is not executed until the surrounding function returns. |
| |
| .play flowcontrol/defer.go |
| |
| * Stacking defers |
| |
| Deferred function calls are pushed onto a stack. When a function returns, its |
| deferred calls are executed in last-in-first-out order. |
| |
| To learn more about defer statements read this |
| [[/blog/defer-panic-and-recover][blog post]]. |
| |
| .play flowcontrol/defer-multi.go |
| |
| * Congratulations! |
| |
| You finished this lesson! |
| |
| You can go back to the list of [[/tour/list][modules]] to find what to learn next, or continue with the [[javascript:click('.next-page')][next lesson]]. |