Go 1.27 标准库加了 uuid:V4 还是 V7,主键该选哪个
Go 1.27 把 UUID 收进了标准库,新增顶层 uuid 包,用于生成和解析符合 RFC 9562 的 UUID。目前这个包只支持 V4 和 V7 两个版本,对应 NewV4 与 NewV7。
u := uuid.New() // 目前与 NewV4() 等价
u4 := uuid.NewV4() // 显式要一个 V4
u7 := uuid.NewV7() // 时间有序的 V7
uuid.New() 和 uuid.NewV4() 现在完全等价,写哪个都行:习惯简洁用 New(),想让代码读者一眼看出版本就写 NewV4()。具体签名以 go doc uuid 为准。
V4 与 V7 的取舍
一般场景直接用 V4,纯随机,没有额外语义。
真正需要纠结的是把 UUID 拿去当主键、或者放进被索引的数据库列的时候。这种场景考虑 NewV7():V7 按时间有序,前缀带时间戳,对很多数据库(比如 Postgres)的大索引性能更好——插入位置集中,索引页分裂和维护的代价比完全随机的 V4 小。
代价是 V7 会泄露 UUID 的创建时间。这个时间戳是 UUID 内容的一部分,谁能拿到这个 ID,谁就能推出它大概是什么时候生成的。是否可接受取决于业务:如果这个时间点本身敏感(对外暴露会暴露写入节奏、用户注册时间之类),就用 V4;如果不敏感,V7 换来的是索引侧的实打实收益。
从第三方库迁过来
在此之前,Go 里生成 UUID 基本都要引第三方库,google/uuid 是最常见的选择。Go 1.27 之后 uuid 在标准库里,公共 API 的项目可以少一个依赖。
迁移时把 import 换掉,然后核对项目里实际用到的 API 在标准库里的名称与返回签名是否一致,逐个改。别只看包名对上就整体替换。
同一版本里其它标准库变化
encoding/json/v2
新增 encoding/json/v2 与 encoding/json/jsontext。v2 默认更严格:拒绝非法 UTF-8,拒绝对象内的重复名称。现有的 encoding/json 底层改由 v2 驱动,行为尽量保持兼容,但错误消息的文本可能不同——依赖错误字符串做判断的代码要注意。想回到旧实现,用 GOEXPERIMENT=nojsonv2。
crypto/mldsa
新增后量子签名算法 ML-DSA(FIPS 204),已经集成进 crypto/x509 与 crypto/tls。
实验性 simd
simd 与 simd/archsimd 处于实验阶段,需要 GOEXPERIMENT=simd 打开。
net/http/httptest.NewTestServer
net/http/httptest 新增 NewTestServer,配合 testing/synctest 使用,是一个内存里的假网络。
语言变化
- 支持泛型方法。
- 结构体字面量可以用任意字段选择器作为 key。
- 函数类型推断推广到所有赋值场景。
工具链
go fix新增atomictypes、embedlit、slicesbackward、unsafefuncs四组重写。go doc支持package@version查询指定版本。go mod tidy会合并多个require块。
运行时
- size-specialized 内存分配:小于 80B 的小对象分配成本最多降低 30%,整体约 1%。
goroutineleakprofile 转正(GA)。
零散 API 更新
strings.CutLast、bytes.CutLast。hash/maphash支持泛型哈希策略。math/big.Int.Divide增加舍入控制。math/rand/v2的Rand.N变成泛型方法。