Go 1.27 交互式导览
摘要
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 语言服务器可以实现令人印象深刻的代码导航
Go 语言服务器 (gopls) 为 Go 开发者提供了令人印象深刻的代码导航功能,增强了 IDE 的能力。
Go 实验详解
本文介绍了 Go 语言中实验性功能的处理方式、生命周期以及近期实验示例。
观察 Go 的新垃圾回收器在堆中的移动
Go 1.26 将 Green Tea 设为默认垃圾回收器,提升了缓存友好性。本文通过 Go 和 C# 可视化堆分配,并讨论了非移动回收器和稀疏页面带来的挑战。
优化CPU密集型Go热路径的笔记
本文讨论了CPU密集型Go代码的性能优化技术,指出了泛型和接口抽象因无法内联而产生的局限性,并主张在热路径中使用代码复制。文章通过一个Brotli移植示例和深入基准测试进行了说明。
Show HN: Tiny – 一种带有内联Go原生函数的动态解释型语言
Tiny是一种用Go编写的新的动态解释型编程语言,具有字节码虚拟机、JIT编译和内联Go原生函数,以实现高性能。