Go 语言之父介绍泛型


Go 官方博客近日发表了一篇介绍新特性“泛型”的文章,作者是两位重量级人物 —— Robert Griesemer 和 Ian Lance Taylor,内容基于他们在 2021 年 GopherCon 大会上的演讲。 ▲ 左:Go 语言设计者之一 Robert Griesemer;右:Go 泛型主要设计者 Ian Lance Taylor 视频地址: 不久前正式发布的 添加了对泛型的支持,据称泛型是 Go 开源以来所做的最大改变。泛型是一种编程范式,这种范式独立于所使用的特定类型,泛型允许在函数和类型的实现中使用某个类型集合中的任何一种类型。 泛型为 Go 添加了三个新的重要内容: 面向函数和类型的“类型形参” (type parameters) 将接口类型定义为类型集合,包括没有方法的接口类型 类型推断:在大多数情况下,在调用泛型函数时可省略“类型实参” (type arguments) Type Parameters 现在函数和类型都具有类型形参” (type parameters),类型形参列表看起来就是一个普通的参数列表,除了它使用的是方括号而不是小括号。 先从浮点值的基本非泛型 Min 函数开始:
func Min(x, y float64) float64 {
 if x y {
 return x
 return y
}
通过添加类型形参列表来使这个函数泛型化——使其适用于不同的类型。在此示例中,添加了一个带有单个类型形参T的类型参数列表,并替换了float64。
import "golang.org/x/exp/constraints"
func GMin[T constraints.Ordered](x, y T) T {
 if x y {
 return x
 return y
}
然后就可以使用类型实参调用此函数:
x := GMin[int](2, 3)
向GMin提供类型参数,在这种情况下int称为实例化。实例化分两步进行。首先,编译器在泛型函数或泛型类型中用所有类型形参替换它们各自的类型实参。然后,编译器验证每个类型形参是否满足各自的约束。如果第二步失败,实例化就会失败并且程序无效。 成功实例化后,即可产生非泛型函数,它可以像任何其他函数一样被调用。比如:
fmin := GMin[float64]
m := fmin(2.71, 3.14)
GMin[float64]的实例化产生了一个与Min函数等效的函数,可以在函数调用中使用它。类型形参也可以与类型一起使用。
type Tree[T interface{}] struct {
 left, right *Tree[T]
 value T
func (t *Tree[T]) Lookup(x T) *Tree[T] { ... }
var stringTree Tree[string]
在上面的例子中,泛型类型Tree存储了类型形参T的值。泛型类型也可以有方法,比如本例中的Lookup。为了使用泛型类型,它必须被实例化;Tree[string]是使用类型实参string来实例化Tree的示例。 类型推断 此项功能是最复杂的变更,主要包括: 函数参数类型推断 (Function argument type inference) 约束类型推断 (Constraint type inference) 虽然类型推断的工作原理细节很复杂,但使用它并不复杂:类型推断要么成功,要么失败。如果它成功,类型实参可以被省略,调用泛型函数看起来与调用普通函数没有什么不同。如果类型推断失败,编译器将给出错误消息,在这种情况下,只需提供必要的类型实参。 泛型是 Go 1.18 的重要新语言特性,Robert Griesemer 和 Ian Lance Taylor 表示,这个功能实现得很好并且质量很高。虽然他们鼓励在有必要的场景中使用泛型,但在生产环境中部署泛型代码时,请务必谨慎。 。

相關推薦

2022-03-03

持了泛型(也称作类型参数)。泛型是 Go 1 发布以来 Go 语言最重要的变化,同时也是有史以来最大的单一语言特性变化。 近日开发团队介绍了他们如何通过字典 (dictionaries) 和 GC Shape Stenciling 在 Go 1.18 中实现泛型。 泛

2022-09-13

Go 博客发布了 2022 年第二季度 Go 开发者调查报告。据介绍,总共有 5752 名开发者参与了本次调查,分享了他们使用 Go 1.18 中新特性的经验和心得。 主要发现 泛型已被迅速采用。大多数受访者都知道 Go 1.18 已正式支持泛型

2022-11-12

Go 语言开发团队技术 leader Russ Cox 在博客中庆祝 Go 开源 13 周年。2009 年 11 月 10 日,Go 作为开源项目正式宣布推出,目前已开源 13 周年。   对于 Go 来说,2022 是非常重要的一年,这一年  Go 发布了 Go 1.18 和 G

2022-07-27

办的 CppNorth 大会上宣布,正式开源谷歌内部打造的编程语言 Carbon,并号称 Carbon 是 C++ 的继任者(目前处于实验性阶段)。此举不可避免的在 C++ 社区中引发了很多讨论,同时也引来了 C++ 之父 Bjarne Stroustrup 的回应。 在被外媒

2023-01-24

LiteIDE X38.1 发布,支持 Go1.18 泛型。 * 支持 Go1.18 泛型,支持泛型/实例的代码完成,查找和重构支持。 * 改进环境变量,编辑器,代码完成和集成终端等插件。 * 支持 VS2019 和 FreeBSD/OpenBSD 编译。   ### 2023.01.22 Ver X38.1 * LiteIDE

2023-02-03

在美国国家安全局 (NSA) 建议组织从 C/C++ 切换到内存安全语言 (如 C#、Rust、Go、Java、Ruby 或 Swift) 之后。C++ 之父 Bjarne Stroustrup 回应称,在他看来,NSA 报告中提到的“安全”编程语言在重要应用程序中实际上并不优于 C++。

2023-02-14

LiteIDE X38.2 正式发布。 更新 gotools & gocode,修复泛型代码查找和代码完成。 重构 Go 类视图和大纲视图,支持泛型显示。 更新 Delve 调试插件,增加反汇编视图,修复 windows 下退出错误。 ### 2023.02.14 Ver X38.2 * LiteIDE * fix

2022-09-06

时间就创建了第一个版本的 JavaScript,这是一门动态编程语言,其语法与 Sun 的 Java 语言大致相似。由于这种合作关系,Sun拥有了“JavaScript”商标。2009 年,Oracle 收购了 Sun Microsystems,并因此获得 "JavaScript" 商标。 RD 指出,"JavaSc

2024-08-15

Go 编程语言开发团队今天凌晨正式发布 Go 1.23。 此版本带来了众多改进和新特性,下面简单看看主要亮点。 一. 语言特性更新 新的迭代器语法: 在"for-range"循环中,现在可以使用迭代器函数作为range表达式,如func(func(K) bool)

2022-07-06

这对编写内核和没有 FPU 的嵌入式系统很有用 TCC 现在与语言捆绑在一起,这允许在不依赖外部 C 编译器的情况下构建 V 程序 Null 可以只在 unsafe 的情况下使用 新模块 compress.gzip 大量的 net/ net.http/ vweb 修正 支持 IPv6 Go2V

2023-01-17

领域,这次演讲内容涉及的主题也很广泛,涵盖了从编程语言如何演变到项目如何失败的方方面面。 Gosling 谈到了 Java 对于 AWS 的重要性。据他介绍,AWS 许多核心功能都采用 Java 实现,而且它拥有相当庞大的 Java 工程师团队—

2023-02-03

新增重要功能 增加时光回溯功能 所谓时光回溯功能,就是加大视频流在服务器的缓存,可以通过配置publish下的buffertime来控制缓存多久。例如可以缓存7秒视频,那么服务器就会至少缓存7秒音视频数据,当我们需要

2023-05-18

29% 的受访者表示,他们已经在任何所想的领域使用了 Go 语言,但扩大使用量的前两个领域分别是 GUI / Desktop 和 AI / ML  应用;且在不同组织规模和工作角色的群体中都是这样。但就经验水平而言,新手更愿意使用 Go 的第

2022-07-31

出警告。 自动 SQL 检测 SQL 语句现在可被自动检测 ,语言将被注入到与特定模式匹配的每个字符串文字。 将语言注入字符串文字时,如果编辑该文字,您将获得全面的代码辅助。 可以在 Preferences | Editor | Language Injections(