Golang - 哪些情况可以出现panic错误(开发中遇到了哪些坑)
一、除数为0
a := 1
b := 0
c := a / b
fmt.Println(c)

二、调用接口未实现的方法
三、数组下标越界、字符串越界(运行时错误,对于静态类型语言,数组下标越界是致命错误)
1)数组下标越界
package main
import "fmt"
func main() {
var s []string
fmt.Println(s)
fmt.Println(s[0])
}

2)字符串越界
字符串是不可变的值类型,内部用指针指向UTF-8字节数组。
a := "123"
b := a[2]
fmt.Println(b) // 51,数字3的ASCII码十进制数为51
c := a[3] //发生panic,字符串数组下标超界了
fmt.Println(c)

四、空指针引用(访问未初始化的指针或 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 的 chanel 里发送数据
正常关闭之后,写入会panic,读取元素是channel的零值(因为元素已经取完,如果没有取完,正常还是读到里面的元素)
ch := make(chan int)
fmt.Println(ch) //0xc00004c060
close(ch) //可以正常关闭,此时不会panic
go func() {
ch <- 1 //已经关闭之后再写入,会panic
//a := <-ch
//fmt.Println(a) //如果是读取元素会打印channel int的零值:0
}()
time.Sleep(time.Second)

2)关闭为nil的channel
new 的作用是初始化一个指向类型的指针(*T),使用new函数来分配空间,返回值是指向这个新分配的零值的指针。
ch := new(chan int)
fmt.Println(*ch) //nil
if *ch == nil {
fmt.Println("ch 为nil")
} else {
fmt.Println("ch 不为nil")
}
close(*ch) //nil,会panic

make 的作用是为slice,map或chan初始化并返回引用对象(T),返回一个有初始值的对象【注意不是指针】。
ch := make(chan int)
fmt.Println(ch) //0xc00009a000
if ch == nil {
fmt.Println("ch 为nil")
} else {
fmt.Println("ch 不为nil")
}
close(ch) //可以正常关闭,不会panic

3)关闭一个已经关闭的channel
ch := make(chan int)
fmt.Println(ch) //0xc00009a000
close(ch) //可以正常关闭,不会panic
close(ch) //重复关闭,会panic

七、死锁,所有线程睡眠(致命错误)
线程不安全(slice、map)的数据结构,多线程并发操作
八、给空map赋值
map未初始化,可读不可写。
map的value如果是结构体指针,使用时先判空。
即nil map写数据会panic,可以读
var map1 map[string]int
if map1 == nil {
fmt.Println("map1为nil")
}
fmt.Println("第1次打印map1:", map1) //可以读
map1["test"] = 1 //写会发生panic
fmt.Println("第2次打印map1:", map1)

九、并发读写相同的map(对于并发读写 map 的地方,应该对 map 加锁)
十、递归死循环或者超出栈空间
浙公网安备 33010602011771号