Go's control syntax is designed to be very simple and can be written with a minimum of reserved words. Therefore, there are many variations in the description method, so I will summarize them.
The first is the ** if statement ** that controls conditional branching. The basic form of the if statement is as follows.
if conditional expression{
Processing when conditions are met
}else if conditional expression{
Processing when the first conditional expression is not satisfied
} else {
Processing when all conditional expressions are not satisfied
}
By the way, the conditional expression must be a bool value.
You can set a simple statement by separating the conditional expression with a semicolon.
x, y := 5, 10
if a := x * y; a == 50 {
fmt.Println("Variable a is 50")
} else {
fmt.Println("Variable a is a mystery")
} //Variable a is 50
You can also use the if statement to handle errors.
import (
"os"
"log"
)
func test() error {
_, e := os.Open("test.txt")
return e
}
func main() {
if err := test(); err != nil {
log.Fatal(err) //test.Since the file called txt does not exist, an error message is output.
}
}
As I wrote in the previous article (About Go functions) [https://qiita.com/noa-1129/items/589d514b4eda0cf9c632 "Qiita"), this time I divided the functions into two and handled the error. I am doing it. Simply put, it defines a function that takes the error interface as a return value and opens a fictitious file "test.txt" in the os package. The function is received by the main function and the error is determined.
In Go, the only syntax for describing loops is for. The following is a naked for that is not specified. For for executes an infinite loop if nothing is specified.
for {
fmt.Println("Naked for") //infinite loop
}
You can write a typical for statement that you often see by arranging the initialization statement, conditional expression, and post-processing by separating them with a semicolon.
for a := 0; a < 10; a++ {
fmt.Println(a) //0 1 2 3 4 5 6 7 8 9
}
A for statement that defines a range expression using the ** reserved word range **.
tests := [3]string{ "test1", "test2", "test3" }
for i, a := range tests {
fmt.Printf("[%d]%s\n", i, a) //[0]test1
//[1]test2
//[2]test3
}
In this program, the index of the array is assigned to i and the value of the variable tests is assigned to the variable a, and the array and the index are repeatedly looped.
Iterative processing for character string type is also possible using range, but it is output as a character code in Unicode from the point where the iterative value becomes ** rune type **. In addition, the index of the string is repeated for each UTF-8 encoded code point, so the amount of index increment varies depending on the code point of the character.
The switch statement is a process in which a simple statement is arbitrarily placed, the expression is evaluated, and branch processing is performed. In addition, the switch statement has two processes: a switch statement with a ** expression ** and a switch statement with a ** type **.
switch simple statement(;)formula{
Each branch process...
}
Below is a switch statement using an expression.
switch a := 2; a {
case 1:
fmt.Println("Is 1")
case 2:
fmt.Println("2") //output
case 3:
fmt.Println("3")
case 4:
fmt.Println("4")
case 5:
fmt.Println("5")
default:
fmt.Println("Mysterious value")
The expression in which 2 is assigned to the variable a is evaluated and branch processing is performed.
It is also possible to set an expression in the case and perform branch processing.
b, c := 1, 5
switch a := 5; a {
case b + c:
fmt.Println("addition")
case b - c:
fmt.Println("subtraction")
case b * c:
fmt.Println("Multiplication") //output
case b / c:
fmt.Println("Divide")
5 is assigned to the variable a, and branch processing is performed from the expression set in each case.
You can easily write a switch statement using a type by performing branch processing in combination with a type assertion.
var x interface{} = 5
switch a := x.(type) { //Type assertion formula
case int:
fmt.Println(a * a) //output//25
case bool:
fmt.Println("bool type")
case string:
fmt.Println("string type")
default:
fmt.Println("Mysterious value")
}
This program defines a variable with an interface {} type that is compatible with all types, and branches the value from an expression that uses a function called ** type assertion ** that dynamically checks the type. I am doing it.
** break statement ** as a function to interrupt loop processing There is a ** continue statement ** as a function to skip the remaining processing and continue to the next loop processing.
break.go
a := 0
for {
fmt.Println(a)
a++
if a == 10 {
break //Processing is interrupted when the variable a becomes 10.
}
}
continue.go
for a := 0; a < 10; a++ {
if a == 5 {
continue
}
fmt.Println(a) //When the variable a becomes 5, skip its value
}
By combining labels with break and continue statements, you can jump to any position even if there are multiple nests. ** Label: Defines the position in the form of **.
break.go
a := 5
EXIT:
for {
for {
for {
fmt.Println(a * a) //25
break EXIT
}
fmt.Println(a + a) //Not output
}
fmt.Println(a - a) //Not output
}
fmt.Println("DONE") //DONE
I have defined the label EXIT and escaped at break EXIT.
Next is the case of using the continue statement.
continue.go
SKIP:
for a := 1; a <= 5; a++ {
for b := 1; b <= 5; b++ {
if b > 1 {
continue SKIP
}
fmt.Printf("a = %d, b = %d\n", a, b) //a = 1, b = 1
} //a = 2, b = 1
fmt.Println("Don't come here") //a = 3, b = 1
} //a = 4, b = 1
//a = 5, b = 1
The for is double nested and the loop is skipped if there are more b than 1 for the inner for. In other words, you can see that the inner loop has only been executed once.
** defer ** can register an expression that will be executed when the function finishes.
func main() {
defer fmt.Println("defer1")
defer fmt.Println("defer2")
fmt.Println("This is first") //This is first
} //defer2
//defer1
As a caveat, there is a point that it is output from the formula registered later.
You can also register multiple defers by using an anonymous function.
defer func() {
fmt.Println("defer1")
fmt.Println("defer2")
fmt.Println("defer3")
}()
Next, defer can also be used to close a file to prevent omissions when opening the file.
File open process...
}
defer file.Close()
You can use the go statement to generate a ** goroutine ** that is processed in parallel.
func test() {
tests := [...]string{ "test1", "test2", "test3" }
for i, a := range tests {
fmt.Printf("[%d]%s\n", i, a)
}
}
func main() {
go test()
mains := [3]string{ "main1", "main2", "main3" }
for i, b := range mains {
fmt.Printf("[%d]%s\n", i, b)
}
}
Execution result
[0]main1
[1]main2
[2]main3
[0]test1
[1]test2
[2]test3
By doing ``` go test ()` `` in the main function, the goroutine of the test function is generated and parallel processing is performed irregularly. By the way, if you make the array type the same, it will not work well, so be careful.
It also works the same if you use an anonymous function.
This time, I summarized the control syntax! I think control syntax is a frequent process, so I want to understand it well ~
Recommended Posts