Go Fiber中slice append字符串后所有元素被修改问题咨询
问题根源
你遇到的问题是Go Fiber的默认内存复用机制导致的,和Go语言本身的slice特性无关,这也是你加锁后问题依旧存在的原因:
Fiber为了提升性能,默认会复用请求生命周期内的底层字节缓冲区,c.BodyParser解析得到的字符串w.Whatever本质是直接引用了请求的底层缓冲区,没有做独立拷贝。当请求结束后,这块缓冲区会被Fiber回收复用给后续请求,你之前存在slice里的所有字符串因为都是指向同一块复用的缓冲区,自然会被后续请求的内容覆盖,出现所有元素同步修改的现象。
你之前添加的互斥锁仅能解决slice并发读写的竞争问题,和本次字符串引用被覆盖的问题完全无关,所以加锁后故障没有消失。
解决方案
有两种常用的修复方式:
方式1:手动拷贝字符串(推荐,性能损耗低)
在存入slice之前,对解析得到的字符串做一次独立拷贝,切断和Fiber请求缓冲区的引用关系:
app.Post("/", func(c *fiber.Ctx) error { w := new(Whatever) if err := c.BodyParser(w); err != nil { return err } // 手动做一次拷贝,得到独立的字符串 safeItem := string([]byte(w.Whatever)) itemsMu.Lock() items = append(items, safeItem) log.Println(items) itemsMu.Unlock() return c.Redirect("/") })
方式2:开启全局Immutable配置
修改Fiber初始化配置,开启Immutable参数,开启后所有从请求上下文中获取的字符串都会自动做独立拷贝,无需手动处理,但会有轻微的性能损耗:
app := fiber.New(fiber.Config{ Views: engine, Immutable: true, // 全局开启请求数据自动拷贝 })
内容的提问来源于stack exchange,提问作者Eduard Khiaev
相关产品推荐
相关产品推荐

