哪些情况可以出现panic错误

发布时间 2023-12-30 14:32:20作者: 李若盛开

一、数组下标越界(运行时错误,对于静态类型语言,数组下标越界是致命错误)

package main
import "fmt"
func main() {
    var s []string
    fmt.Println(s)
    fmt.Println(s[0])
}

二、空指针引用(访问未初始化的指针或 nil 指针)

直接引用空指针结构体的字段会引发panic,但调用成员方法里如果没引用结构体的字段不会引发panic,有引用到字段还是会panic

package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

func (p *Person) getName() string {
    fmt.Println(p.Name)
    return ""
}

func (p *Person) doNothing() string {
    fmt.Println("doNothing")
    return ""
}

func main() {
    var p *Person
    fmt.Println(p)      //nil
    fmt.Println(p.Name) //panic
    p.getName()         //会panic
    p.doNothing()       //不会panic
}

三、类型断言失败(接口转换异常)

    a := UserPb{}
    var b interface{}
    b = a
    c := b.(string)
    fmt.Println(c)

四、channel相关

1)试图往已经 close 的 chan 里发送数据
3)关闭为nil的channel
3)关闭一个已经关闭的通道
4)关闭一个还有发送阻塞go队列的chan,关闭时会后会唤醒发送阻塞的go协程继续写数据,此时chan已关闭,触发panic: send on closed channel

五、死锁,所有线程睡眠(致命错误)
六、给空map赋值

    var map1 map[string]int
    if map1 == nil {
        fmt.Println("map1为nil")
    }
    fmt.Println("第1次打印map1:", map1)
    map1["test"] = 1
    fmt.Println("第2次打印map1:", map1)

七、并发读写相同的map(对于并发读写 map 的地方,应该对 map 加锁。)
八、递归死循环,堆栈溢出