Go 1.27 交互式导览

Lobsters Hottest 新闻

摘要

Go 1.27 新功能的实践性交互式导览,重点介绍泛型方法、结构体字面量字段选择器等,并提供基于官方发布说明的可运行示例。

<p><a href="https://lobste.rs/s/7ibjyl/go_1_27_interactive_tour">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/07/31 12:47

# Go 1.27 交互式导览 来源:https://victoriametrics.com/blog/go-1-27/index.html Go 1.27 即将发布,现在是提前了解新特性的好时机。官方发布说明比较枯燥,所以这里提供一个动手实践版本,包含可运行示例,展示有哪些变化以及新行为如何工作。 先快速致谢:Go 交互式导览最初由 Anton Zhiyanov 发起,他为 Go 1.22 到 Go 1.26 的每个版本都写了一篇。他已经决定停止更新,所以我们从他停下的地方继续。他之前的导览仍然都值得一读: - [Go 1.22 interactive tour](https://antonz.org/go-1-22/) - [Go 1.23 interactive tour](https://antonz.org/go-1-23/) - [Go 1.24 interactive tour](https://antonz.org/go-1-24/) - [Go 1.25 interactive tour](https://antonz.org/go-1-25/) - [Go 1.26 interactive tour](https://antonz.org/go-1-26/) 谢谢,Anton。 在深入新特性之前,我们先交代一下背景。 本文基于官方发布说明和 Go 源代码编写,遵循 BSD-3-Clause 许可。这不是一份详尽的清单;完整内容请参阅[官方发布说明](https://go.dev/doc/go1.27)。 链接指向每个特性的文档(D)、提案(P)、最相关的提交(CL)和作者(A);可以查看它们了解动机、用法和实现细节。作者(A)是对该特性做出贡献的人(编写实现、测试,或者对于从先前实验毕业的特性,是最初设计者),不一定只有一位主要作者。 为了保持示例简洁,通常省略错误处理。请勿在生产环境中这样做 ツ ## 泛型方法 这是本版本的重头戏。现在,[方法声明](https://go.dev/ref/spec#Method_declarations)可以声明它**自己的**类型参数,独立于接收者的类型参数。在 Go 1.27 之前,只有顶层函数可以是泛型的,因此对某个类型的泛型操作只能作为包级函数存在,而不能作为方法。 假设我们有一个泛型容器,并想要一个可以改变元素类型的 `Map` 操作: ```go type Box[T any] struct{ v T } // 该方法声明自己的类型参数 U(Go 1.27 新增)。 func (b Box[T]) Map[U any](f func(T) U) Box[U] { return Box[U]{v: f(b.v)} } ``` 现在 `Map` 是 `Box` 的方法,可以将 `int` 盒子转换为 `string` 盒子: ```go func main() { b := Box[int]{v: 21} doubled := b.Map(func(n int) int { return n * 2 }) label := doubled.Map(func(n int) string { return fmt.Sprintf("value=%d", n) }) fmt.Println(label.v) } ``` 有一个重要限制:接口仍然不能声明带类型参数的方法,泛型方法也不能用来满足接口。把泛型方法放进接口,编译器会阻止你: ```go type Mapper interface { Map[U any](f func(int) U) any // 接口不能声明泛型方法 } ``` ``` interface method must have no type parameters ``` - D:[Generic methods](https://go.dev/ref/spec#Method_declarations) - P:[77273](https://go.dev/issue/77273) - CL:[524b8606](https://github.com/golang/go/commit/524b8606a8)、[e84da04](https://github.com/golang/go/commit/e84da0405bcf64c7dbaafb0afc14388049a9b6fc)、[e212a16](https://github.com/golang/go/commit/e212a16d1e) - A:[Robert Griesemer](https://github.com/griesemer)、[Mark Freeman](https://github.com/mrkfrmn) ## 结构体字面量字段选择器 [结构体字面量](https://go.dev/ref/spec#Composite_literals)中的键现在可以是该结构体类型的任意有效字段选择器,而不仅仅是顶层字段名。实际上这意味着你可以直接设置**提升**字段(来自嵌入结构体的字段),而不必写出嵌入类型。 ```go type Base struct { ID int } type User struct { Base Name string } ``` 在 Go 1.27 之前,你必须写 `User{Base: Base{ID: 7}, Name: "Mittens"}`。现在提升的 `ID` 可以直接作为键使用: ```go u := User{ID: 7, Name: "Mittens"} fmt.Println(u.ID, u.Name) ``` - D:[Composite literals](https://go.dev/ref/spec#Composite_literals) - P:[9859](https://go.dev/issue/9859) - CL:[

相似文章

Go 实验详解

Lobsters Hottest

本文介绍了 Go 语言中实验性功能的处理方式、生命周期以及近期实验示例。

观察 Go 的新垃圾回收器在堆中的移动

Lobsters Hottest

Go 1.26 将 Green Tea 设为默认垃圾回收器,提升了缓存友好性。本文通过 Go 和 C# 可视化堆分配,并讨论了非移动回收器和稀疏页面带来的挑战。

优化CPU密集型Go热路径的笔记

Hacker News Top

本文讨论了CPU密集型Go代码的性能优化技术,指出了泛型和接口抽象因无法内联而产生的局限性,并主张在热路径中使用代码复制。文章通过一个Brotli移植示例和深入基准测试进行了说明。