zhcn 编程语言 Golang Golang 容器 非公開: Go语言崩溃(panic)——程序终止

Go语言崩溃(panic)——程序终止

尽管Go语言的类型系统在编译时检测到许多错误,但有些错误,例如越界数组访问和空指针引用,只能在运行时检查。这些运行时错误会导致停机。

停机并不是一件好事。就像您不想在取款时遇到 ATM 机蓝屏一样,它会降低您的体验并扰乱您的服务。然而,如果停机不能停止程序,那么停机是一种合理的止损方式,因为任何损失都可能使用户付出更高的金钱、时间、甚至生命的代价。

一般情况下,当发生宕机时,程序会暂停运行,立即执行goroutine(最初可以理解为线程)内的延迟函数(延迟机制),导致程序崩溃并输出日志信息。信息包括恐慌值和函数调用的堆栈跟踪。恐慌值通常是某种错误消息。

每个 goroutine 的日志信息包括发生恐慌时相应的函数调用堆栈跟踪信息。通常,您不需要再次运行该程序来识别问题。日志信息提供了足够的诊断证据。当您填写问题报告时,通常会包括停机时间和日志记录信息。

虽然Go语言的panic机制和其他语言的异常类似,但是panic的应用场景略有不同。恐慌可能会导致程序崩溃,因此恐慌通常用于严重错误,例如程序内的逻辑不匹配。对于大多数错误,您应该使用Go语言提供的错误机制而不是panic,因为崩溃表明您的代码中可能存在错误。

手动触发停机

Go语言允许在程序内手动触发宕机导致程序崩溃,让开发者能够及时捕获错误,减少可能的损失。

当 Go 程序崩溃时,它会将堆栈和 goroutine 信息打印到控制台,这对于查看错误发生的位置很有用。

 package main

func main() {
    panic("crash")
} 

该代码运行并崩溃,输出如下:

panic: crash

Goroutine 1 [运行]:
main.main()
D:/code/main.go:4 +0x40
退出状态2

上面的代码仅使用内置函数Panic()来导致崩溃。 panic()的声明如下:

 func panic(v interface{})    //panic()の引数は任意の型にできます。 

当运行依赖项所需的资源不足时主动触发停机。

regexp是Go语言的正则表达式包。正则表达式必须经过编译才能使用,编译必须成功才表明该正则表达式是可用的。

已编译的正则表达式函数有两种类型:

1)func Compile(expr string) (*Regexp, 错误)

它编译正则表达式,如果发生错误则返回编译错误,并将 Regexp 返回为 nil,因此对于想要捕获编译错误并在继续执行时处理它们的环境来说,它是一个很好的函数。

2) func MustCompile(str string) *Regexp

如果编译正则表达式时发生错误,请使用panic触发关闭。该功能适用​​于直接使用正则表达式而不处理正则表达式错误的情况。

MustCompile的代码如下:

 func MustCompile(str string) *Regexp {
    regexp, error := Compile(str)
    if error != nil {
        panic(`regexp: Compile(` + quote(str) + `): ` + error.Error())
    }
    return regexp
} 

代码说明如下:

  • 第1行编译正则表达式函数入口,输入包含正则表达式的字符串,并返回正则表达式对象。
  • 第二行的Compile()是编译正则表达式的入口函数,并返回编译后的正则表达式对象和任何错误。
  • 第 3 行和第 4 行决定在发生错误时使用panic() 来触发关闭。
  • 如果没有错误,第 6 行将返回一个正则表达式对象。

手动关闭并报告错误并不是一个偷懒的方法。相反,您可以快速报告错误,终止程序并继续运行,并防止发生更大的错误。然而,利用停机时间并不是一个好的设计实践。因此,您应该根据您的需求决定是否使用停机时间进行错误报告。

停机期间触发语句的延迟执行

当发生由 Panic() 引起的停机时,panic() 之后的代码不会被执行,但在发生停机时,panic() 函数之前执行的 defer 语句仍然有效。请参阅下面的代码。

 package main

import "fmt"

func main() {
    defer fmt.Println("ダウンタイム後に行うこと 1")
    defer fmt.Println("ダウンタイム後に行うこと 2")
    パニック("「ダウンタイム」")
} 

这是代码输出:

ダウンタイム後に行うこと 2
ダウンタイム後に行うこと 1
panic: 「ダウンタイム」

Goroutine 1 [运行]:
main.main()
D:/code/main.go:8 +0xf8
退出状态2

代码解释:

  • 第 6 行和第 7 行使用 defer 语句来延迟两个语句。
  • 8号公路发生事故。

停机前,先执行defer语句。第7行的defer是在宕机之后执行的,所以在宕机之前先处理这个defer,然后再处理第6行的defer对应的语句。使用 在发生停机之前处理停机信息。

通俗易懂地解释“Go语言崩溃(panic)——程序终止”!您必须观看的最佳 2 个视频

【たった1時間で学べる】Go言語のプログラミング初心者向けの超入門講座【文字書き起こし、ソースコードも完全無料!】
https://www.youtube.com/watch?v=kPXfMFJ0oIE&pp=ygVSIEdvIOiogOiqnuOBruOCr-ODqeODg-OCt-ODpSAo44OR44OL44OD44KvKSAtIOODl-ODreOCsOODqeODoOOBjOe1guS6huOBmeOCiyZobD1KQQ%3D%3D
はじめてのGolang Part2 Webフレームワーク Gin 前編
https://www.youtube.com/watch?v=CXIC3-mUzzc&pp=ygVSIEdvIOiogOiqnuOBruOCr-ODqeODg-OCt-ODpSAo44OR44OL44OD44KvKSAtIOODl-ODreOCsOODqeODoOOBjOe1guS6huOBmeOCiyZobD1KQQ%3D%3D
尽管Go语言的类型系统在编译时检测到许多错误,但有些错误,例如越界数组访问和空指针引用,只能在运行时检查。这些运行时错误会导致停机。

停机并不是一件好事。就像您不想在取款时遇到 ATM 机蓝屏一样,它会降低您的体验并扰乱您的服务。然而,如果停机不能停止程序,那么停机是一种合理的止损方式,因为任何损失都可能使用户付出更高的金钱、时间、甚至生命的代价。

一般情况下,当发生宕机时,程序会暂停运行,立即执行goroutine(最初可以理解为线程)内的延迟函数(延迟机制),导致程序崩溃并输出日志信息。信息包括恐慌值和函数调用的堆栈跟踪。恐慌值通常是某种错误消息。

每个 goroutine 的日志信息包括发生恐慌时相应的函数调用堆栈跟踪信息。通常,您不需要再次运行该程序来识别问题。日志信息提供了足够的诊断证据。当您填写问题报告时,通常会包括停机时间和日志记录信息。

虽然Go语言的panic机制和其他语言的异常类似,但是panic的应用场景略有不同。恐慌可能会导致程序崩溃,因此恐慌通常用于严重错误,例如程序内的逻辑不匹配。对于大多数错误,您应该使用Go语言提供的错误机制而不是panic,因为崩溃表明您的代码中可能存在错误。

手动触发停机

Go语言允许在程序内手动触发宕机导致程序崩溃,让开发者能够及时捕获错误,减少可能的损失。

当 Go 程序崩溃时,它会将堆栈和 goroutine 信息打印到控制台,这对于查看错误发生的位置很有用。

 package main

func main() {
    panic("crash")
} 

该代码运行并崩溃,输出如下:

panic: crash

Goroutine 1 [运行]:
main.main()
D:/code/main.go:4 +0x40
退出状态2

上面的代码仅使用内置函数Panic()来导致崩溃。 panic()的声明如下:

 func panic(v interface{})    //panic()の引数は任意の型にできます。 

当运行依赖项所需的资源不足时主动触发停机。

regexp是Go语言的正则表达式包。正则表达式必须经过编译才能使用,编译必须成功才表明该正则表达式是可用的。

已编译的正则表达式函数有两种类型:

1)func Compile(expr string) (*Regexp, 错误)

它编译正则表达式,如果发生错误则返回编译错误,并将 Regexp 返回为 nil,因此对于想要捕获编译错误并在继续执行时处理它们的环境来说,它是一个很好的函数。

2) func MustCompile(str string) *Regexp

如果编译正则表达式时发生错误,请使用panic触发关闭。该功能适用​​于直接使用正则表达式而不处理正则表达式错误的情况。

MustCompile的代码如下:

 func MustCompile(str string) *Regexp {
    regexp, error := Compile(str)
    if error != nil {
        panic(`regexp: Compile(` + quote(str) + `): ` + error.Error())
    }
    return regexp
} 

代码说明如下:

  • 第1行编译正则表达式函数入口,输入包含正则表达式的字符串,并返回正则表达式对象。
  • 第二行的Compile()是编译正则表达式的入口函数,并返回编译后的正则表达式对象和任何错误。
  • 第 3 行和第 4 行决定在发生错误时使用panic() 来触发关闭。
  • 如果没有错误,第 6 行将返回一个正则表达式对象。

手动关闭并报告错误并不是一个偷懒的方法。相反,您可以快速报告错误,终止程序并继续运行,并防止发生更大的错误。然而,利用停机时间并不是一个好的设计实践。因此,您应该根据您的需求决定是否使用停机时间进行错误报告。

停机期间触发语句的延迟执行

当发生由 Panic() 引起的停机时,panic() 之后的代码不会被执行,但在发生停机时,panic() 函数之前执行的 defer 语句仍然有效。请参阅下面的代码。

 package main

import "fmt"

func main() {
    defer fmt.Println("ダウンタイム後に行うこと 1")
    defer fmt.Println("ダウンタイム後に行うこと 2")
    パニック("「ダウンタイム」")
} 

这是代码输出:

ダウンタイム後に行うこと 2
ダウンタイム後に行うこと 1
panic: 「ダウンタイム」

Goroutine 1 [运行]:
main.main()
D:/code/main.go:8 +0xf8
退出状态2

代码解释:

  • 第 6 行和第 7 行使用 defer 语句来延迟两个语句。
  • 8号公路发生事故。

停机前,先执行defer语句。第7行的defer是在宕机之后执行的,所以在宕机之前先处理这个defer,然后再处理第6行的defer对应的语句。使用 在发生停机之前处理停机信息。

通俗易懂地解释“Go语言崩溃(panic)——程序终止”!您必须观看的最佳 2 个视频

【たった1時間で学べる】Go言語のプログラミング初心者向けの超入門講座【文字書き起こし、ソースコードも完全無料!】
https://www.youtube.com/watch?v=kPXfMFJ0oIE&pp=ygVSIEdvIOiogOiqnuOBruOCr-ODqeODg-OCt-ODpSAo44OR44OL44OD44KvKSAtIOODl-ODreOCsOODqeODoOOBjOe1guS6huOBmeOCiyZobD1KQQ%3D%3D
はじめてのGolang Part2 Webフレームワーク Gin 前編
https://www.youtube.com/watch?v=CXIC3-mUzzc&pp=ygVSIEdvIOiogOiqnuOBruOCr-ODqeODg-OCt-ODpSAo44OR44OL44OD44KvKSAtIOODl-ODreOCsOODqeODoOOBjOe1guS6huOBmeOCiyZobD1KQQ%3D%3D