Short Circuit Evaluation
According to Go's documentation, the sentence "The right operand is evaluated conditionally" points out that Go will only examine the expression if it is required.
To better understand why we should handle errors, consider the following example.
The result is coming if users input an integer 1:
The result is coming if users input a string "hello":
According to this example, if we did not check the "err" and access the value directly. Then we will get the incorrect value such as 0 in this example.
The standard approach to utilize a "if statement" is shown below.
We can use Simple Statement (Short If) to adjust it.
'args' can be used by 'else if', and 'intValue' from 'else if' can be used by 'else'.
Let's revise the preceding example:
Result:
The "switch statement" searches for an equal value.
In the switch case, you can specify multiple conditions.
Refer to this doc.
The "fallthrough" statement instructs the flow to proceed to the next case block without checking the condition.
Result:
We can use the simplified version of Go to remove the switch condition (true).
Keep in mind that the separator ';' tells Go that this is a short switch, not a standard switch.
A block of code is repeated as long as its condition is true.
// Outer Loop
Then we can use labeled break to keep the remaining code in the loop.
// Go will check the second expression
fmt.Println(true && false)
// Go will only check the first expression if it returns false,
// and the rest such as second expressions are not meaningful to check.
fmt.Println(false && true)
If Statement
Unlike other languages, "Go" does not require parenthesis (unless where absolutely necessary).
The code block of a "if statement" is executed only if its condition expression is true.
Variables specified in this code block are also visible exclusively in this code block (block scope).
Error Handling
Everything does not always go as planned.
As a result, we must decide what to do when errors occur.
As an example:
1. A network problem or a downed web server
2. Incorrect input from users (missing some arguments? or by providing the incorrect type of input)
nil is a predefined identifier, similar to true and false, and indicates that the value has not yet been initialized.
Other languages have the similar identifier like nil:
1. javascript -> null
2. python -> None
3. jave -> null
nil is the zero value for pointer-based types:
1. pointers
2. slices
3. maps
4. interfaces
5. channels
We can utilize nil in 'Go' to determine whether or not a function answer contains an error.
value, error = getValueAndError()
if error != nil {
// Instead of processing the value, handle the error.
// Then terminate the program
return
}
// If there is no error, keep going
Error value and example
// We use 'ParseInt' because we assume users will input an integer
value, err := strconv.ParseInt(os.Args[1], 10, 64)
fmt.Println("value ", value)
fmt.Println("err: ", err)
The result is coming if users input an integer 1:
value 1
err: <nil>
The result is coming if users input a string "hello":
value 0
err: strconv.ParseInt: parsing "hello": invalid syntax
According to this example, if we did not check the "err" and access the value directly. Then we will get the incorrect value such as 0 in this example.
Simple Statement (Short If)
The standard approach to utilize a "if statement" is shown below.
intValue, err := strconv.ParseInt(os.Args[1], 10, 64)
if err != nil {
return
}
fmt.Println("result", intValue)
We can use Simple Statement (Short If) to adjust it.
if intValue, err := strconv.ParseInt(os.Args[1], 10, 64); err == nil {
fmt.Println("result ", intValue)
}
More Details:
1. ;, which is the separator, separate the simple statement and the condition expression.
2. The condition expression can use the declared variables inside the simple statement.
3. Declared variables are only visible inside the if statement (and its branches)
Consider the following complicated example to better grasp the scope of a simple statement:
if args := os.Args; len(args) == 1 {
fmt.Println("Input should not be empty")
} else if intV, err := strconv.ParseInt(args[1], 10, 64); err != nil {
fmt.Println("Invalid input")
} else {
fmt.Println("result ", intV)
}
'args' can be used by 'else if', and 'intValue' from 'else if' can be used by 'else'.
Shadowing
Let's revise the preceding example:
intV := 0
if args := os.Args; len(args) == 1 {
fmt.Println("Input should not be empty")
} else if intV, err := strconv.ParseInt(args[1], 10, 64); err != nil {
fmt.Println("Invalid input")
} else {
fmt.Println("result ", intV)
}
fmt.Println("intValue:", intV)
result 1
intV: 0
Because "if statement" creates its own code block, and Go detects that the variable intValue has already been declared outside of this scope, Go will construct a variable with the same name but only visible within this scope.
It's known as variable shadowing.
Switch
The "switch statement" searches for an equal value.
month := "January"
switch month {
case "January":
fmt.Println("It is Jan")
case "Feburary":
fmt.Println("It is Feb")
}
More Details:
1. 'month' is a condition expression
2. Switch's condition expression determines the type of the 'case condition'
3. Case clause creates an exclusive block only for itself
4. The default clause is executed when no cases match.
It equals the following code (using the "if statement") from the preceding example:
month := "January"
if month == "January" {
fmt.Println("It is Jan")
}
More Details:
Only one case code block will be executed in Go.
Unlike other programming languages, Go will automatically include a 'break' statement at the end of each case code block. Refer to this doc.
In Go, just one case code block will be run.
Multiple conditions
In the switch case, you can specify multiple conditions.
age := 17
switch age {
case 16, 17, 18:
fmt.Println("Senior High School")
case 13, 14, 15:
fmt.Println("Junior High School")
case 7, 8, 9, 10, 11, 12:
fmt.Println("Elementary School")
}
Bool Expression
Another switch format supported by Go is shown below.
The bool statement can be used as a switch condition statement.
score := 60
switch true {
case score >= 85:
fmt.Println("A")
case score >= 75:
fmt.Println("B")
case score >= 75:
fmt.Println("C")
case score >= 55:
fmt.Println("D")
default:
fmt.Println("F")
}
Because the switch expression is boolean (true), the case clause can also utilize bool expression.
We can also eliminate the switch expression because Go will set it to 'true' by default.
score := 60
switch {
case score >= 85:
fmt.Println("A")
case score >= 75:
fmt.Println("B")
case score >= 75:
fmt.Println("C")
case score >= 55:
fmt.Println("D")
default:
fmt.Println("F")
}
Fallthrough switch
Refer to this doc.
The "fallthrough" statement instructs the flow to proceed to the next case block without checking the condition.
switch i := 15; {
case i > 20:
fmt.Println("Hi-1")
fallthrough
case i > 10:
fmt.Println("Hi-2")
fallthrough
case i > 5:
fmt.Println("Hi-3")
default:
fmt.Println("Hi-4")
}
Hi-2
Hi-3
Short Switch
It is similar idea like 'Short If'.
The standard format is provided below.
To separate the simple statement (score:= 60) and switch condition (true), we need to add the separator ';'.
switch score := 60; true {
case score >= 85:
fmt.Println("A")
case score >= 75:
fmt.Println("B")
case score >= 75:
fmt.Println("C")
case score >= 55:
fmt.Println("D")
default:
fmt.Println("F")
}
We can use the simplified version of Go to remove the switch condition (true).
switch score := 60; {
case score >= 85:
fmt.Println("A")
case score >= 75:
fmt.Println("B")
case score >= 75:
fmt.Println("C")
case score >= 55:
fmt.Println("D")
default:
fmt.Println("F")
}
Keep in mind that the separator ';' tells Go that this is a short switch, not a standard switch.
If V.S. Switch
If your "if statement" contains hard to read/understand code, try changing it to a "switch statement."
Loops
A block of code is repeated as long as its condition is true.
for i := 1; i < 5; i++ {
fmt.Println(i)
}
More Details:
1. 'i := 1' is the initial state, which will be executed only once.
2. 'i < 5' is a bool condition expression, which will be checked before entering each loop step.
3. 'i++' is the post statement, which will be run after each step of the loop.
While Go does not support "while" syntax, you can use the format below with "break".
i := 1
for {
if i >= 5 {
break
}
fmt.Println(i)
i++
}
Using continue
By using the continue statement, you can skip the rest of the current phase.
Label Statement
We may come across a circumstance where we need to break the nested loop from inner to outer.
Consider the following example, which contains two nested "for loops" (one outer and one inner).
words := strings.Fields(corpus)
query := os.Args[1:]
for _, q := range query {
// Inner Loop
for _, w := range words {
if q == w {
fmt.Println("Found it", w)
break
}
}
}
Our goal is to exit this nested for loop when a condition in the inner loop is met.
How are we going to do it?
We can label it as "labeled break" and refer to it as such.
"Labeled break" breaks from the labeled statement.
ords := strings.Fields(corpus)
query := os.Args[1:]
outerLoop:
for _, q := range query {
for _, w := range words {
if q == w {
fmt.Println("Found it", w)
break outerLoop
}
}
}
The same as "labeled break," we may use "labeled continue" to exist the inner loop while continuing to execute the outer loop.
ords := strings.Fields(corpus)
query := os.Args[1:]
outerLoop:
for _, q := range query {
for _, w := range words {
if q == w {
fmt.Println("Found it", w)
continue outerLoop
}
}
}
If there is a switch inside a for loop, the break command will only exist as a switch code block, and the rest of the code inside the for loop will be performed continuously.
ords := strings.Fields(corpus)
query := os.Args[1:]
outerLoop:
for _, q := range query {
for _, w := range words {
switch (w) {
case "pass":
break;
}
if q == w {
fmt.Println("Found it", w)
continue outerLoop
}
}
}
ords := strings.Fields(corpus)
query := os.Args[1:]
outerLoop:
for _, q := range query {
innerLoop:
for _, w := range words {
switch (w) {
case "pass":
break innerLoop
}
if q == w {
fmt.Println("Found it", w)
continue outerLoop
}
}
}
Goto
Navigate to a label.
It can hop practically anywhere inside the same function to any label.
Here's an example of how to use Goto to create a for loop.
counter := 0
myLoop:
if counter < 5 {
counter++
fmt.Println("Counter++")
goto myLoop
}
fmt.Println("Final Counter", counter)
No comments:
Post a Comment