Skip to content

golang可能的panic场景

约 491 字大约 2 分钟

2025-05-21

golang 开发过程中, 会有很多并发不安全的场景, 如果没有合适的处理, 很容易会导致panic, 下面是一些常见的场景

map相关

并发读写

map 并发读取不会出现问题, 并发读+写会panic, 并发写+写也会panic, 冲突如下

并发操作
允许panic
panicpanic

首先, map 是 非并发安全 的, 并发读写会panic, 但是不是一定会panic, 所以不要赌小概率事件, 示例如下:

func mapModify() {
	mapData := map[string]any{
		"key": "value",
	}
	wg := &sync.WaitGroup{}
	wg.Add(6)
	for i := 0; i < 3; i++ {
		go func() {
			defer wg.Done()
			fmt.Println(mapData["key"])
		}()
		go func() {
			defer wg.Done()
			mapData["key"] = time.Now()
		}()
	}
	wg.Wait()
}

上面这段代码, 本地执行, 有很大几率不会panic, 但是并不是说代码没问题, 上面代码为了演示, 简化了逻辑, 在工程化场景下, 逻辑复杂, 高频读取, 基本是会panic, 包的. 将上述逻辑调整成如下代码, 模拟高频读写:

func mapModify() {
	mapData := map[string]any{
		"key": "value",
	}
	wg := &sync.WaitGroup{}
	wg.Add(6)
	for i := 0; i < 3; i++ {
		go func() {
			defer wg.Done()
			for {
				fmt.Println(mapData["key"])
			}
		}()
		go func() {
			defer wg.Done()
			for {
				mapData["key"] = time.Now()
			}
		}()
	}
	wg.Wait()
}

上述代码会稳定报错: fatal error: concurrent map writes , 代表了map并发读写导致panic

未初始化map写

func opNilMap() {
	var mapData map[string]any
	fmt.Println(mapData["name"])
	mapData["name"] = "value"
}

上述代码, 仅声明map, 但是未初始化, 访问会有问题, 但是会发现, 读取是正常的, 说明 NIL Map是支持数据读取的, 返回对应value的零值 , 但是, 设置数据的时候, 会产生panic: panic: assignment to entry in nil map

slice相关

索引越界

slice扩容

slice截取修改

结构体调用(未分配结构体地址)

强制类型转换

Released under the MIT License.