In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly introduces the Go language panic function, recover function and defer statement how to use, has a certain reference value, interested friends can refer to, I hope you can learn a lot after reading this article, the following let Xiaobian with you to understand.
Panic
Another way of handling errors in the panic,Go language. Strictly speaking, it does not deal with errors, but exceptions, and is a kind of program exception that we did not expect.
Panic details
To analyze the panic details, first generate a panic. For example, in a slice, its length is 5, but it is incorrect to access the elements through index 5. Such as the following:
Func main () {l: = [] int {1,2,3,4,5} _ = l [5]}
When the program is running, it throws a panic when this line of code is executed, indicating that the user's index is out of bounds. It's not just a hint. When the panic is thrown, if no protection is added to the program, the program (or the process that represents it) will stop running after printing out the details of the pinic. Here are the details of panic:
Panic: runtime error: index out of rangegoroutine 1 [running]: main.main () H:/Go/src/Go36/article21/example01/main.go:5 + 0x3dexit status 2
Take a look at the first line, where "runtime error" indicates that this is a panic thrown from a runtime code package. In this panic, there is a value of runtime.Error interface type. The runtime.Error interface embeds the error interface and extends it a little bit, and there are many of its implementation types in the runtime package. In fact, the content to the right of "panic:" is a string representation of the value of the runtime.Error type contained in this panic.
In addition, one of the panic details contains code execution information about the goroutine related to the cause of the cause. The "goroutine 1 [running]:" here indicates that a goroutine with an ID of 1 was running when the panic was raised.
Looking at the next line, "main.main ()" indicates that the go function wrapped by this goroutine is the main function in the command source file. The next line indicates the absolute path to the source file and the line on which the code is in the file. The last + 0x3d of this line represents the offset of this line of code relative to the entry program of the function to which it belongs. But usually this is of no use to us.
The last "exit status 2" is the status code for the exit of the program. In most operating systems, as long as the exit status code is not 0, it ends abnormally. In the GE language, the exit status code for a program that ends running due to panic is usually 2.
The process from the initiation of a panic to the termination of a program
Let's start with a rough process: when a panic is raised.
At this point, the initial panic details are established, and control of the program is immediately transferred from this line of code to the line of code that calls the function to which it belongs, one level up the call stack. This means that the execution of the function to which this line of code belongs terminates immediately.
Immediately after that, control does not stop at the current location, and it immediately transfers to the calling code at the next level. Control is relayed to the top in the direction of the call stack, which is the outermost function we have written. The outermost function is the go function, which is the main function for the main goroutine. But the transfer of control does not stop at this point, but is reclaimed by the system of the Go speech runtime.
Then, the program crashes and terminates, and the process running this time dies and disappears. In the process of spreading control, panic details are gradually accumulated and perfected and printed out before the program is terminated.
I would like to add that the meaning of a function raising panic is completely different from that of a function returning an error value.
When a function returns a non-nil error value, the caller of the function has the right to choose not to handle it, and the consequences of not dealing with it are often non-fatal.
When a panic occurs, if no protection is imposed, the result is a program crash, which is obviously fatal.
The following example clearly shows the upward propagation of control described above:
Package mainimport "fmt" func main () {fmt.Println ("main Start") caller1 () fmt.Println ("main End")} func caller1 () {fmt.Println ("caller1 Start") caller2 () fmt.Println ("caller1 End")} func caller2 () {fmt.Println ("caller2 Start") l: = [] int {1,2,3,4,5} _ = l [5] fmt.Println ("caller2 End")}
Here, the details of panic will be gradually accumulated and improved in the process of spreading control. Also, control propagates to the top in the opposite direction of the call stack. Therefore, in the code execution information for a goroutine, the information at the bottom of the call stack appears first, followed by the information called at the next level. And so on, the last is the information at the top of the call stack.
So, the main function calls the caller1 function, and the caller1 function calls the caller2 function. Then the information about the execution of the code in the caller2 function appears first, then the execution information of the code in the caller1 function, and finally the information of the main function:
PS H:\ Go\ src\ Go36\ article21\ example02 > go run main.gomain Startcaller1 Startcaller2 Startpanic: runtime error: index out of rangegoroutine 1 [running]: main.caller2 () H:/Go/src/Go36/article21/example02/main.go:20 + 0xa2main.caller1 () H:/Go/src/Go36/article21/example02/main.go:13 + 0x77main.main () H:/Go/src/Go36/article21/example02/main.go:7 + 0x77exit status 2PS H:\ Go\ src\ Go36\ article21\ example02 >
At this point, you should already have some understanding of the process of program termination after panic is triggered. An in-depth understanding of this process and the correct interpretation of panic details is an essential skill. This is useful when debugging Go programs or troubleshooting errors for Go programs.
Panic function, recover function and defer statement
If a panic is raised by us inadvertently, then the value in it can only be given by the Go language runtime system. However, when we use the panic function to intentionally raise a panic, we can specify the value it contains.
Panic function
When calling a panic function, just pass a value as an argument to the function. The panic function has only one argument, and the type is an empty interface, so syntactically, it can accept any type of value. Once the program is abnormal, the relevant information about the exception must be recorded, so you need to use a string representation of the output parameter. Although functions such as fmt.Sprintf and fmt.Fprintf that can be formatted and output parameters also meet the requirements. However, it is recommended to use custom Error or String methods in terms of functionality. Therefore, it is the first choice to write these two methods for different data types. In this way, when the program crashes, the string representation of the value contained in panic will be printed out:
Package mainimport ("fmt" / / "errors") func caller () {fmt.Println ("caller Start") / / panic (errors.New ("Something Wrong")) / / positive panic (fmt.Errorf ("Something Wrong% s") "2") / / positive example / / panic (fmt.Println) / / counterexample} func main () {fmt.Println ("main Start") caller () fmt.Println ("main End")} recover function
Protection against panic can be imposed to prevent the program from crashing. The built-in function recover of the Go language is specifically used to restore panic. Recover takes no arguments and returns a value of an empty interface type. This return value is a copy of the parameter passed in by panic.
Let's look at an erroneous usage:
Func main () {fmt.Println ("main Start") panic (errors.New ("Something Wrong")) p: = reover () fmt.Println (p) fmt.Pringln ("main End")}
Here, after raising the panic, I want to call the recover function immediately. However, the execution of the function ends on the line panic, and the call to the recover function has no chance to be executed at all. To call the recover function correctly, you need to use the defer statement. Here is the revised code:
Package mainimport ("fmt"errors") func main () {fmt.Println ("main Start") defer func () {fmt.Println ("defer Start") if p: = recover () P! = nil {fmt.Printf ("Panic:% s\ n", p)} fmt.Println ("defer End")} () panic (errors.New ("Something Wrong")) fmt.Println ("main End")}
In this main function, a defer statement is written first, and then the recover function is called in the defer function. The contents of the panic are printed only if the result of the call is not nil, that is, the panic has actually occurred. Here, try to write the defer statement at the beginning of the function body, because all statements after raising the panic statement will not have any chance of execution.
Defer statement
Defer languages are used to delay the execution of code. Delay until the end of the execution of the function in which the statement is located, regardless of the reason for ending execution (including panic).
Like other go statement types, a defer statement consists of a defer keyword and a calling expression. There are some limitations, and there are some call expressions that cannot appear here: the call expression for the function inside the Go statement, and the call expression for the function in the unsafe package. Here the called function can have a name or an internal name. The function here is called the defer function or the delay function. Note that it is the defer function that is being delayed, not the defer statement.
Defer execution order
If there are multiple defer statements in a function, the order in which defer functions are called is exactly the opposite of the order in which the defer statements to which they belong are executed. When a function is about to finish execution, the defer function call written at the bottom is the latest, and the defer function call in the top table is the last.
Each time a defer statement is executed, the Go language stores its defer function and its parameter values in a separate queue. This queue corresponds to the function to which the defer statement belongs, and it is FILO, thinking of a stack. When the defer function call of a function needs to be executed, the Go language will first get the corresponding queue, and then extract the defer function and its parameter values from the queue and execute the call one by one. This is why this order of execution is implemented.
The following is a simple example that shows the order in which defer is called:
Package mainimport "fmt" func main () {defer fmt.Println ("first defer") for I: = 0; I < 3 ITunes + {defer fmt.Printf ("defer in for [% d]\ n", I)} defer fmt.Println ("last defer")} Thank you for reading this article carefully. I hope the article "how to use panic function, recover function and defer statement in Go language shared by the editor will be helpful to you. At the same time, I hope you will support us, pay attention to the industry information channel, and more related knowledge is waiting for you to learn!"
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.