Go问答技术文章
-
errors.Unwrap 只调用 Unwrap() error,适合单链包装;errors.Join 返回值实现的是 Unwrap() []error,所以直接调用得到 nil。匹配原因应使用 errors.Is 或 errors.As,枚举时再显式处理多子错误接口。122 收藏 -
Go errors.Join 会生成实现 Unwrap() []error 的多分支错误树。errors.Is 会检查根错误并深度优先遍历每个子错误,因此可对多个原因逐个匹配;直接等号和 errors.Unwrap 不适用于该结构。309 收藏 -
Go SectionReader 通过 base、当前偏移和 limit 建立固定读取窗口。本文解释 Read 的缓冲区裁剪、ReadAt 的相对偏移、EOF、Seek 与 Size 的边界语义。161 收藏 -
io.Copy 不一定走缓冲循环:它会优先调用 WriterTo 或 ReaderFrom。本文用调用顺序、CopyBuffer 边界和适配器示例说明自定义缓冲区为什么没有生效,以及如何正确控制这条路径。239 收藏 -
Go 的 io.Reader 可以在一次 Read 中同时返回 n > 0 和 io.EOF。正确顺序是先处理 buf[:n],再判断 err;否则会丢掉输入流最后一段有效数据。本文给出通用循环、错误优先级、0,nil 边界与标准库替代方案。330 收藏 -
Go 对字符串执行 for range 时,如果遇到非法 UTF-8,第二个迭代值会是 U+FFFD(utf8.RuneError),下一轮只前进一个字节。本文解释字节索引、连续非法序列、合法 U+FFFD 的歧义,以及 ValidString 和 DecodeRuneInString 的正确用法。385 收藏 -
strings.EqualFold 按 Unicode 简单大小写折叠直接判断两个 UTF-8 字符串,而 strings.ToLower 是把字符单向映射成小写。本文用希腊 Sigma、德语 ß 和组合字符说明两者差异、适用场景与工程边界。229 收藏 -
Go 的 string 按字节存储,直接切片可能把多字节 UTF-8 字符截在中间,产生非法编码。本文用可复现代码说明原因,并给出按 rune 截取与按合法字节边界截取的选择方法。494 收藏 -
Go 内置 copy 对源和目标切片的重叠有语言规范保证,复制结果不受内存区间是否重叠影响。本文给出切片左移删除、右移插入的可靠写法,并说明返回数量、容量和并发边界。283 收藏 -
本文解释 Go 删除切片元素后大对象仍可能被底层数组尾部指针保持可达的原因,对比手动 clear 与 Go 1.22+ slices.Delete,并说明别名切片、GC 时机、堆复用和 RSS 判断边界。174 收藏 -
Go append 是否复用底层数组取决于容量。本文用 len、cap 和独立复制示例说明新旧切片互相影响的原因,并给出需要隔离时的处理方案。465 收藏 -
Go 的 float64 虽然能作为 map 键,但 NaN 与自身也不相等,导致查找和 delete 无法重新命中已写入条目。本文演示问题,并给出入口拦截、clear、过滤重建和稳定键编码方案。332 收藏 -
Go 规范明确规定 map 遍历顺序未指定,同一 map 的多次 range 也不保证一致。需要稳定输出时,应先收集键并排序,再按键读取值;测试则按目标选择 maps.Equal 或确定性序列化。455 收藏 -
Go 普通 map 并发读写时,runtime 的 map 专用检查可能先触发 fatal,而 race detector 只有在使用 -race 构建且冲突路径实际执行时才会报告。本文给出识别、止血、定位和修复方法。218 收藏 -
本文解释 Go CompareAndSwap 为什么只能确认当前值,沿着 A→B→A 时序说明 ABA 风险,并给出指针与版本号绑定、生命周期和重试边界的处理方法。466 收藏