This is the 8th day of my participation in Gwen Challenge
Short step, no thousands of miles; Not small streams, beyond into rivers and seas. Steed leap, not ten steps, ten inferior horse riding, gongnot give up. Stop chipping halfway, deadwood can’t be broken; Constant dripping wears away the stone.
In the previous analysis of Singleflight, I saw that “the doCall method cleverly uses two defer to distinguish calling function exceptions from system exceptions”. Today, I will search for information and learn about the exception handling mechanism of Go. I only know one keyword panic in my current general impression.
Exceptions and errors
In Go, errors are considered an expected result; An exception is an unexpected result that may indicate a BUG or other uncontrollable problem in the program.
In Go, errors and anomalies are mainly expressed through error and panic [2]
For example, when querying a result from a map, success can be judged by additional Booleans as an expected result.
if v, ok := m["key"]; ok {
return v
}
Copy the code
error
error
Error type in Go: error
type error interface {
Error() string
}
Copy the code
The built-in Error interface allows developers to add any information they need for errors, which can be any type of implementation of the Error() method, as shown in [2][5].
The errors package in Go provides several commonly used functions, including errors.New, errors.Is, errors.As, errors.Unwrap, and the use of FMT.Errorf.
Erros. Is determines whether two errors are equal, and error.As determines whether an error Is of a specific type.
Using the instance
A function can usually return an error message on the last return value, a simple example:
package main
import (
"errors"
"fmt"
)
func myF(f float64) (float64, error) {
if f < 0 {
return 0, errors.New("Not legal input ")}/ / implementation
return 0.0.nil
}
func main(a) {
var m map[string]string
m = make(map[string]string)
m["a"] = "2"
_, ok := m["a"]
_, ok2 := m["b"]
fmt.Println(ok) // true
fmt.Println(ok2) // false
_, e := myF(- 1)
_, e2 := myF(2)
fmt.Println(e) // Not legal input
fmt.Println(e2) // <nil>
}
Copy the code
abnormal
Please defer and Panic Recover can handle exceptions.
defer
When an exception occurs in a program, such as an “unexpected” error such as an out-of-bounds access, it can cause the program to crash, requiring the developer to catch the exception and restore the program to normal flow. Catching exceptions is not the end goal. If the exception is unpredictable, the best way to deal with it is to directly output the exception information [1].
Defer is a deferred execution mechanism provided by Go, and each time it is executed, the corresponding function is pushed onto the stack. At the end of a function return or panic exception, Go in turn pulls the delayed function execution from the stack.
panic
Panic is used to actively throw exceptions that are executed by the program, terminating the code that is to be executed afterwards, and executing in reverse order the list of defer functions that panic might have.
recover
The recover keyword is used to catch exceptions and restore the program state from serious errors to normal state. It must be in the defer function to take effect.
Here is a code sample from defer+ Panic + Recover. As you can see, the output from defer was executed after manual panic, and the value of a is 0, so the name function should return an error if there is a panic statement in the function.
package main
import "fmt"
func main(a) {
for i := 0; i < 10; i++ {
a := my(i)
fmt.Println(a)
}
}
func my(i int) int {
defer func(a) {
if err := recover(a); err ! =nil {
fmt.Println("Something abnormal has occurred.", err)
}
}()
ifi ! =5 {
return i
} else {
panic("panic")}return - 1
}
Copy the code
Code output:
An exception occurs. Panic 0, 4Copy the code
A processing extreme
Super robust code, adding the following code at the beginning of each function:
func myfunc(a) {
defer func(a) {
if err := recover(a); err ! =nil {
fmt.Println(err)
}
}()
// Function implementation....
}
Copy the code
Of course, don’t do it all the time
[1] Errors and exceptions
[2] How do I handle Go error exceptions without a try-catch
[3] Some potholes of defer in Go
[4] Go – Panic and recover
[5] Part 31: Custom Error in Golang