6.1. Error
The error interface under builtin package is used as error type in Go language
Errors in the Go language are used as return values of methods/functions
Customize error types
//Learn_Go/main.go package main import ( "errors" "fmt" ) func demo(i,k int) (r int, e error) { if k == 0 { e = errors.New("The divisor cannot be zero") return } r = i/k return } func main() { //result,error := demo(6,3) result,e := demo(6,0) if e != nil{ fmt.Println("Execution error, error message is:",e) //Error message: divisor cannot be 0 return } fmt.Println("Successful implementation resulted in:",result) //Successful implementation, results:2 }
6.2.defer
Defer can complete defer function in Go language, and defer function is executed after the current function is executed
The most common use of defer is to close the connection (database, file, etc.). You can open the connection and close it immediately after defer.
(1) In Go, defer is the last execution wherever it is written, so you don't have to write the closing code at the end.
//Learn_Go/main.go package main import "fmt" func main() { fmt.Println("Open Connection") // defer fmt.Println("Close Connection") defer func() { fmt.Println("Close Connection")//defer execution }() fmt.Println("Operation") } // Results open a connection Operating Close the connection
(2) multiple defer s
Multiple defer s are executed using stack structure, first generated and then executed
In many code structures, it is possible to generate multiple objects, and the program expects these objects to be turned off backwards, which can be solved by multiple defer s
//Learn_Go/main.go package main import "fmt" func main() { fmt.Println("Open Connection A") defer fmt.Println("Close Connection A") fmt.Println("Open Connection B") defer fmt.Println("Close Connection B") fmt.Println("Open Connection C") defer fmt.Println("Close Connection C") fmt.Println("Operation") } // Results Open Connection A Open Connection B Open Connection C Operating Close Connection C Close connection B Close connection A
(3) Combination of defer and return
When defer and return exist at the same time, return should be understood as a combination of two executions. One instruction is to give the return value.
Assignment, another instruction returns the jump-out function
The overall execution sequence for defer and return
- Assign the return value first
- Execute defer
- Return the jump-out function
(4) No return value receiving variable is defined, and the return value has been assigned when defer is executed.
//Learn_Go/main.go package main import "fmt" func demo() int { i := 1 defer func() { i = i + 2 }() return i } func main() { fmt.Println(demo()) //1 }
(5) Declare that the return value variable is received, and modify the return value content when defer is executed
//Learn_Go/main.go package main import "fmt" func demo() (z int) { i := 1 defer func() { z = i + 2 }() return } func main() { fmt.Println(demo()) //3 }
6.3.panic
Panic is a function in build. When it is executed to panic, it terminates the execution of the remaining code and prints the error stack information.
//Learn_Go/main.go package main import "fmt" func main() { fmt.Println("111") panic("error message") fmt.Println("222") } //Result 111 panic: error message goroutine 1 [running]: main.main() C:/Users/86158/Desktop/Learn_Go/main.go:8 +0x82
panic does not stop the program immediately, defer does.
//Learn_Go/main.go package main import "fmt" func main() { defer fmt.Println("implement defer Contents") fmt.Println("111") panic("error message") fmt.Println("222") } //Result 111 //Executing defer content panic: error message goroutine 1 [running]: main.main() C:/Users/86158/Desktop/Learn_Go/main.go:9 +0xdc
6.4.recover
Recovery () represents panic() of the reply program, allowing the program to execute normally.
rcover() is a builtin function like panic. It can accept panic information and resume normal execution of programs.
Recovery () is usually inside defer, returning nil if there is no panic information; if there is panic, recover y will cancel panic status
//Learn_Go/main.go package main import "fmt" func main() { defer func() { if error := recover();error != nil{ fmt.Println("panic For:", error) } }() fmt.Println("111") panic("Error message appears") fmt.Println("222") } //Result 111 panic For: Error message appears
panic and recovery () during function call
- Recovery () can only restore panic() at the current function level or in the current function call function. After recovery, the call to the current level function ends, but the function calling this function can continue to execute.
- Panic will always pass up, if there is no recovery (), then the program terminates, but when recover(), the level function of recovery () indicates that there is no panic, panic will not pass up.
//Learn_Go/main.go package main import "fmt" func demo1() { fmt.Println("demo1 The first half") demo2() fmt.Println("demo1 The second half") } func demo2() { fmt.Println("demo2 The first half") demo3() fmt.Println("demo2 The second half") } func demo3() { fmt.Println("demo3 The first half") panic("demo3 Appearance panic") fmt.Println("demo3 The second half") } func main() { fmt.Println("Procedure begins") demo1() fmt.Println("End of Procedure") } //Result //Procedure begins demo1 The first half demo2 The first half demo3 The first half panic: demo3 Appearance panic
demo3 adds recover()
//Learn_Go/main.go package main import "fmt" func demo1() { fmt.Println("demo1 The first half") demo2() fmt.Println("demo1 The second half") } func demo2() { fmt.Println("demo2 The first half") demo3() fmt.Println("demo2 The second half") } func demo3() { defer func() { recover() }() fmt.Println("demo3 The first half") panic("demo3 Appearance panic") fmt.Println("demo3 The second half") } func main() { fmt.Println("Procedure begins") demo1() fmt.Println("End of Procedure") } //Result //Procedure begins demo1 The first half demo2 The first half demo3 The first half demo2 The second half demo1 The second half //End of Procedure
demo2 adds recover()
//Learn_Go/main.go package main import "fmt" func demo1() { fmt.Println("demo1 The first half") demo2() fmt.Println("demo1 The second half") } func demo2() { defer func() { recover() }() fmt.Println("demo2 The first half") demo3() fmt.Println("demo2 The second half") } func demo3() { fmt.Println("demo3 The first half") panic("demo3 Appearance panic") fmt.Println("demo3 The second half") } func main() { fmt.Println("Procedure begins") demo1() fmt.Println("End of Procedure") } //Result //Procedure begins demo1 The first half demo2 The first half demo3 The first half demo1 The second half //End of Procedure