golang中可触发panic的几种情况汇总

作者:

文章目录
  • 使用 recover 和 defer 可以捕获 panic,防止程序崩溃: func safeFunc() { defer func() { if r := recover(); r != nil { fmt.Println(“Recovered from panic:”, r) } }() // 可能触发 panic 的代码 panic(“something went wrong”) } func main() { safeFunc() fmt.Println(“Program continues after recovery”) }
  • 触发场景 示例 解决方法 显式调用 panic panic("error") 根据业务逻辑合理使用 数组/切片越界 arr[10] 检查索引范围 空指针解引用 *ptr 检查指针是否为 nil 类型断言失败 i.(int) 使用 i.(type) 安全断言 Channel 操作错误 向已关闭的 channel 发送数据 检查 channel 状态 内存/资源耗尽 创建超大数据结构 优化内存使用,避免无限递归 并发读写 map 无锁的并发写入 使用 sync.Map 或加锁 其他运行时错误(除零、溢出等) 10/0、无限递归 检查输入合法性,合理设计逻辑 通过合理使用 defer 和 recover,可以有效捕获 panic,避免程序崩溃。但应优先使用 error 类型处理可恢复的错误,仅在严重错误时使用 panic。 到此这篇关于golang中可触发panic的几种情况汇总的文章就介绍到这了,更多相关golang 可触发panic内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客! 您可能感兴趣的文章: Golang中panic的实现示例 golang panic 函数用法示例详解 GoLang中panic和recover作用详解 Golang使用panic控制程序错误流程 Golang中的panic之避免和处理程序中的异常情况 一文详细谈谈GoLang的panic和error Golang中panic的异常处理 小学生也能看懂的Golang异常处理recover panic golang panic及处理机制
  • 目录
    • 一. 触发panic 的场景
      • 1. 显式调用panic函数
      • 2. 运行时错误
        • 2.1 数组/切片越界
        • 2.2 空指针解引用
        • 2.3 类型断言失败
        • 2.4 除数为 0
        • 2.5 字符串越界
      • 3. Channel 操作错误
        • 3.1 向已关闭的 channel 发送数据
        • 3.2 关闭 nil channel
      • 4. 内存或资源耗尽
        • 4.1 内存分配失败
        • 4.2 堆栈溢出(无限递归)
      • 5. 并发问题
        • 5.1 无锁的并发读写 map
      • 6. 其他场景
        • 6.1 调用未实现的方法
        • 6.2 错误的defer使用
    • 二. 如何处理 panic?
      • 三. 总结

        在 Go 语言中,panic 是一种运行时错误处理机制,当程序遇到无法恢复的严重错误时会触发 panic。以下是常见的触发 panic 的场景及其示例:

        开发者可以主动调用 panic 函数来触发 panic,通常用于标记程序中无法继续执行的错误(如逻辑错误、资源缺失等)。

        func main() {
            if err := someCriticalCheck(); err != nil {
                panic("Critical error: " + err.Error())
            }
        }
        

        Go 运行时检测到某些非法操作时会自动触发 panic。

        访问数组或切片的索引超出其长度时会触发 panic。

        func main() {
            arr := []int{1, 2, 3}
            fmt.Println(arr[3]) // panic: index out of range
        }
        

        访问未初始化的指针或 nil 指针指向的值时会触发 panic。

        func main() {
            var p *int
            fmt.Println(*p) // panic: runtime error: invalid memory address or nil pointer dereference
        }
        

        当接口类型断言的目标类型与实际类型不匹配时,会触发 panic。

        func main() {
            var i interface{} = "hello"
            s := i.(int) // panic: interface conversion: string is not int
        }
        

        在运行时进行除法操作时,如果除数为 0,会触发 panic。

        func main() {
            result := 10 / 0 // panic: runtime error: integer divide by zero
            fmt.Println(result)
        }
        

        访问字符串的索引超出其长度时会触发 panic。

        func main() {
            s := "abc"
            fmt.Println(s[3]) // panic: string index out of range
        }
        

        对 channel 的非法操作会触发 panic。

        关闭 channel 后,如果再向其发送数据,会触发 panic。

        func main() {
            ch := make(chan int)
            close(ch)
            ch <- 1 // panic: send on closed channel
        }
        

        关闭一个未初始化的 nil channel 会触发 panic。

        func main() {
            var ch chan int
            close(ch) // panic: close of nil channel
        }
        

        当程序运行时内存分配失败或发生堆栈溢出时,会触发 panic。

        创建过大的数据结构可能导致内存不足。

        func main() {
            arr := make([]int, 1<<30) // 可能触发 panic: runtime error: cannot allocate
        }
        

        递归深度过大时会导致堆栈溢出。

        func main() {
            func() {
                defer func() { recover() }()
                infiniteRecursion() // panic: runtime error: stack overflow
            }()
        }
        
        func infiniteRecursion() {
            infiniteRecursion()
        }
        

        某些并发场景下会触发 panic。

        map 的并发读写(未加锁)会导致 panic。

        func main() {
            m := make(map[int]int)
            for i := 0; i < 100; i++ {
                go func() {
                    m[1] = 1 // panic: concurrent map write
                }()
            }
            time.Sleep(time.Second)
        }
        

        如果接口类型变量调用了未实现的方法,会触发 panic。

        type MyInterface interface {
            Method()
        }
        
        type MyStruct struct{}
        
        func (m *MyStruct) Method() {} // 如果没有实现 Method,调用时会 panic
        
        func main() {
            var i MyInterface = MyStruct{} // panic: MyStruct does not implement MyInterface (Method method has pointer receiver)
            i.Method()
        }
        

        defer 中返回值可能被修改时,如果逻辑错误可能导致 panic。

        func main() {
            defer func() {
                if r := recover(); r != nil {
                    fmt.Println("Recovered:", r)
                }
            }()
        
            defer func() {
                panic("defer panic") // panic: defer panic
            }()
        
            panic("main panic")
        }
        

        1. 使用 recoverdefer 可以捕获 panic,防止程序崩溃:
        func safeFunc() {
            defer func() {
                if r := recover(); r != nil {
                    fmt.Println("Recovered from panic:", r)
                }
            }()
        
            // 可能触发 panic 的代码
            panic("something went wrong")
        }
        
        func main() {
            safeFunc()
            fmt.Println("Program continues after recovery")
        }
        

        触发场景 示例 解决方法
        显式调用 panic panic("error") 根据业务逻辑合理使用
        数组/切片越界 arr[10] 检查索引范围
        空指针解引用 *ptr 检查指针是否为 nil
        类型断言失败 i.(int) 使用 i.(type) 安全断言
        Channel 操作错误 向已关闭的 channel 发送数据 检查 channel 状态
        内存/资源耗尽 创建超大数据结构 优化内存使用,避免无限递归
        并发读写 map 无锁的并发写入 使用 sync.Map 或加锁
        其他运行时错误(除零、溢出等) 10/0、无限递归 检查输入合法性,合理设计逻辑

        通过合理使用 deferrecover,可以有效捕获 panic,避免程序崩溃。但应优先使用 error 类型处理可恢复的错误,仅在严重错误时使用 panic。

        到此这篇关于golang中可触发panic的几种情况汇总的文章就介绍到这了,更多相关golang 可触发panic内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!

        您可能感兴趣的文章:

        • Golang中panic的实现示例
        • golang panic 函数用法示例详解
        • GoLang中panic和recover作用详解
        • Golang使用panic控制程序错误流程
        • Golang中的panic之避免和处理程序中的异常情况
        • 一文详细谈谈GoLang的panic和error
        • Golang中panic的异常处理
        • 小学生也能看懂的Golang异常处理recover panic
        • golang panic及处理机制

        站内搜索