Go-Error, defer, panic and recover y

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

Keywords: Python Go Database

Added by rh-penguin on Sat, 10 Aug 2019 10:50:44 +0300