Go 团队在 GopherCon 2021 上的演讲:Go 1.18 泛型简介

Ubuntu安装Go正确姿势:为什么必须用tarball而非apt Go语言是一种静态链接、零依赖的系统级编程语言,其设计哲学强调自包含与版本可控。官方推荐通过二进制分发包(tarball)安装,核心原理在于规避包管理器(如apt)导致的版本滞后、工具链割裂与路径污染问题。该方式保障了GOROOT、PATH和GOPATH等关键环境变量的可预测性与工程一致性,显著提升云原生开发、CI/CD集成及多版本共存场景下的稳定性与可维护性。本文聚焦Ubuntu平台,深入解析tarball安装全流程及其背后的技术逻辑。 阅读详情

介绍

这篇博文基于我们在 GopherCon 2021 上的演讲:

Go 1.18 版本增加了对泛型的支持。泛型是自第一个开源版本以来我们对 Go 所做的最大改变。在本文中,我们将介绍新的语言功能。我们不会试图涵盖所有细节,但我们会触及所有要点。有关更详细和更长的描述,包括许多示例,请参阅提案文档。有关语言更改的更准确描述,请参阅 更新的语言规范。(请注意,实际的 1.18 实施对提案文件允许的内容施加了一些限制;规范应该是准确的。未来的版本可能会取消一些限制。)

泛型是一种编写代码的方式,它独立于所使用的特定类型。现在可以编写函数和类型以使用一组类型中的任何一种。

泛型为语言添加了三个新的重要内容:

  1. 函数和类型的类型参数。

  2. 将接口类型定义为类型集,包括没有方法的类型。

  3. 类型推断,允许在调用函数时在许多情况下省略类型参数。

类型参数

现在允许函数和类型具有类型参数。类型参数列表看起来像一个普通的参数列表(除了它使用方括号而不是圆括号)。

Min 函数 为了展示泛型是如何工作的,让我们从浮点值的基本非泛型函数开始:

func Min(x, y float64) float64 {
    if x < y {
        return x
    }
    return y
}

我们可以通过添加类型参数列表来使这个函数通用,其实就是使其适用于不同的类型。在这个示例中,我们添加了一个带有单个类型参数的类型参数列表T,然后用T来替换float64。

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的的示例。

类型集

让我们更深入地了解可用于实例化类型参数的类型参数。

普通函数对每个值参数都有一个类型;该类型定义了一组值。例如,上面提到的非泛型函数Min,它的参数是float64类型的,所以允许的参数值集是可以由 float64 类型表示的浮点值集。

同样,类型参数列表对每个类型参数都有一个类型。因为类型参数本身就是一种类型,所以类型参数的类型定义了类型集。这种元类型称为 类型约束。

在泛型函数 GMin 中,类型约束是从 constraints 包中导入的。Ordered约束描述了具有可以排序的值的所有类型的集合,或者换句话说,可以通过 < 运算符(或 <= 、 > 等)进行比较。该约束确保只有具有可排序值的类型才能传递给GMin. 这也意味着在GMin函数体中该类型参数的值可以用于与 < 运算符进行比较。

在 Go 中,类型约束必须是接口。即接口类型可以作为值类型,也可以作为元类型。接口定义了方法,因此我们可以表达需要某些方法存在的类型约束。但是constraints.Ordered也是接口类型,< 操作符却不是方法。

为了完成这项工作,我们以一种新的方式看待接口。

直到最近,Go 规范才说接口定义了一个方法集,大致就是接口中枚举的方法集。实现所有这些方法的任何类型都实现了该接口。

8d1033e655d60f3261296295f99ac235.png

但另一种看法是,接口定义了一组类型,即实现这些方法的类型。从这个角度来看,作为接口类型集元素的任何类型都实现了该接口。

56b0d7b651bf677291bcb2bc8a0fceb5.png

这两个视图导致相同的结果:对于每组方法,我们可以想象实现这些方法的相应类型集,即接口定义的类型集。

但是,就我们的目的而言,类型集视图比方法集视图具有优势:我们可以显式地将类型添加到集合中,从而以新的方式控制类型集。

我们扩展了接口类型的语法以使其工作。例如,interface{ int|string|bool }定义包含类型int、string和bool的类型集。

f0762029b62ee031844ae87e2a89c863.png

另一种说法是这个接口只满足int, string, 或bool。

现在让我们看一下 的实际定义contraints.Ordered:

type Ordered interface {
    Integer|Float|~string
}

这个声明说Ordered接口是所有整数、浮点数和字符串类型的集合。竖线表示类型的联合(或本例中的类型集)。 Integer 和 Float中是定义在包constraints中的的接口类型。请注意,接口Ordered中没有定义任何方法。

对于类型约束,我们通常不关心特定类型,例如string; 我们对所有字符串类型都感兴趣,这就是 ~符号的用途。表达式~string表示基础类型为 string的所有类型的集合。这包括类型string本身以及所有使用定义声明的类型,例如type MyString string.

当然,我们仍然希望在接口中指定方法,并且我们希望向后兼容。在 Go 1.18 中,接口除了可以像以前一样包含方法和嵌入式接口外,也可以嵌入非接口类型、联合和底层类型集。

当用作类型约束时,接口定义的类型集准确地指定了允许作为相应类型参数的类型参数的类型。在泛型函数体内,如果操作数的类型是具有约束 C 的类型参数 P,则在 C 的类型集中的所有类型都允许的情况下允许操作(这里目前有一些实现限制,但普通代码不太可能遇到他们)。

用作约束的接口可以被赋予名称(例如Ordered),或者它们可以是内联在类型参数列表中的文字接口。例如:

[S interface{~[]E}, E interface{}]

这里S必须是一个切片类型,其元素类型可以是任何类型。

interface{}因为这是一种常见的情况,约束位置的接口可以省略包围,我们可以简单地写:

[S ~[]E, E interface{}]

因为空接口在类型参数列表和普通 Go 代码中很常见,所以 Go 1.18 引入了一个新的预声明标识符any作为空接口类型的别名。有了这个,我们得到了这个惯用的代码:

[S ~[]E, E any]

作为类型集的接口是一种强大的新机制,是使类型约束在 Go 中起作用的关键。目前,使用新语法形式的接口只能用作约束。但不难想象,明确类型约束的接口在一般情况下会有多大用处。

类型推断

最后一个新的主要语言特性是类型推断。在某些方面,这是对语言最复杂的更改,但它很重要,因为它让人们在编写调用泛型函数的代码时可以使用自然风格。

函数参数类型推断

使用类型参数需要传递类型参数,这可能会产生冗长的代码。回到我们的通用GMin函数:

func GMin[T constraints.Ordered](x, y T) T { ... }
类型参数T用于指定普通非类型参数的类型x,和y。正如我们之前看到的,
这可以使用显式类型参数调用
var a, b, m float64


m = GMin[float64](a, b) // explicit type argument

T在许多情况下,编译器可以从普通参数推断类型参数。这使得代码更短,同时保持清晰。

var a, b, m float64


m = GMin(a, b) // no type argument

这是通过匹配参数的类型a和b参数的类型来实现的x,和y。

这种从函数参数的类型推断类型参数的推断称为 函数参数类型推断。

函数实参类型推断仅适用于函数参数中使用的类型参数,不适用于仅用于函数结果或仅在函数体中的类型参数。例如,它不适用于像 MakeT[T any]() T 这样只使用 T 作为结果的函数。

约束类型推断

该语言支持另一种类型推断,即约束类型推断。为了描述这一点,让我们从这个缩放整数切片的例子开始:

// Scale returns a copy of s with each element multiplied by c.
// This implementation has a problem, as we will see.
func Scale[E constraints.Integer](s []E, c E) []E {
    r := make([]E, len(s)
    for i, v := range s {
        r[i] = v * c
    }
    return r
}

这是一个通用函数,适用于任何整数类型的切片。

现在假设我们有一个多维Point类型,其中每个 Point都是简单的整数列表,给出点的坐标。这种类型会有一些方法。

type Point []int32


func (p Point) String() string {
    // Details not important.
}

有时我们想缩放一个点。由于 Point 只是整数切片,我们可以使用我们之前编写的 Scale 函数:

// ScaleAndPrint doubles a Point and prints it.
func ScaleAndPrint(p Point) {
    r := Scale(p, 2)
    fmt.Println(r.String()) // DOES NOT COMPILE
}

不幸的是,这不会编译,失败并出现类似 r.String undefined (type []int32 has no field or method String).

问题是该Scale函数返回一个[]E类型的值, 其中E是参数切片的元素类型。当我们使用 Point 类型的值调用 Scale时,我们得到一个类型是 []int32 的值,而不是 类型Point 。这遵循通用代码的编写方式,但这不是我们想要的。

为了解决这个问题,我们必须更改Scale函数以使用切片类型的类型参数。

// Scale returns a copy of s with each element multiplied by c.
func Scale[S ~[]E, E constraints.Integer](s S, c E) S {
    r := make(S, len(s))
    for i, v := range s {
        r[i] = v * c
    }
    return r
}

我们引入了一个新的类型参数S,它是切片参数的类型。我们已经对其进行了约束,使得基础类型是S而不是 []E,现在结果类型是 S。由于E被限制为整型,因此效果与之前相同:第一个参数必须是某个整数类型的切片。函数体的唯一变化是:当我们调用make时,我们传递S,而不是[]E,。

如果我们用普通切片调用新函数,它的作用与以前相同,但如果我们用 Point 类型调用它,我们现在会返回一个 Point 类型的值。这就是我们想要的。在这个版本的 Scale 中,早期的 ScaleAndPrint 函数将按照我们的预期编译和运行。

但公平地问:为什么在不传递显式类型参数的情况下编写对 Scale 的调用是可以的?也就是说,为什么我们可以写 Scale(p, 2),没有类型参数,而不是写 Scale[Point, int32](p, 2)?我们的新 Scale 函数有两个类型参数,S 和 E。在调用 Scale 时不传递任何类型参数,函数参数类型推断,如上所述,让编译器推断 S 的类型参数是 Point。但是该函数也有一个类型参数 E。编译器推断 E 的类型参数是切片的元素类型的过程称为约束类型推断。

约束类型推断从类型参数约束中推导出类型参数。当一个类型参数具有根据另一个类型参数定义的约束时使用它。当其中一个类型参数的类型参数已知时,约束用于推断另一个类型参数的类型参数。

这适用的通常情况是,当一个约束对某种类型使用 ~type 形式时,该类型是使用其他类型参数编写的。我们在 Scale 示例中看到了这一点。S 是 ~[]E,它是 ~ 后跟一个类型 []E,用另一个类型参数编写。如果我们知道 S 的类型参数,我们可以推断出 E 的类型参数。S 是切片类型,E 是该切片的元素类型。

这只是对约束类型推断的介绍。有关完整的详细信息,请参阅提案文档 文档或语言规范。

实践中的类型推断

类型推断如何工作的确切细节很复杂,但使用它并不复杂:类型推断要么成功,要么失败。如果成功,可以省略类型参数,调用泛型函数看起来与调用普通函数没有什么不同。如果类型推断失败,编译器将给出错误消息,在这种情况下,我们可以只提供必要的类型参数。

在向语言添加类型推断时,我们试图在推断能力和复杂性之间取得平衡。我们希望确保当编译器推断类型时,这些类型永远不会令人惊讶。我们试图小心地在未能推断类型而不是推断错误类型方面犯错。我们可能还没有完全正确,我们可能会在未来的版本中继续完善它。结果将是可以编写更多程序而无需显式类型参数。今天不需要类型参数的程序明天也不需要它们。

结论

泛型是 1.18 中一个很大的新语言特性。这些新的语言更改需要大量未在生产环境中进行过重大测试的新代码。这只会在更多人编写和使用通用代码时发生。我们相信这个功能实现得很好并且质量很高。然而,与Go的大多数方面不同,我们不能用现实世界的经验来支持这种信念。因此,虽然我们鼓励在有意义的地方使用泛型,但在生产环境中部署泛型代码时请谨慎行事。

除了这个谨慎之外,我们很高兴能有泛型可用,我们希望它们能让 Go 程序员更有效率。

翻译自:https://go.dev/blog/intro-generics

视频:https://www.youtube.com/watch?v=Pa_e9EeCdy8

Go工程师实战:Claude Code、Codex、Qoder、Trae四大AI编程工具深度评测 AI编程助手正从概念走向Go生产环境核心环节——它们不再只是代码补全工具,而是深度参与架构设计、性能调优、依赖治理与线上故障响应的技术协作者。理解其底层定位差异(如上下文感知型、IDE嵌入型、领域建模型、运维诊断型)比单纯比较生成质量更重要。在真实百万行级Go微服务中,工具价值取决于能否准确解析go.mod依赖图、理解sync.Pool生命周期、识别etcd Watch长连接风险、校验JWT密钥注入时机等工程细节。本文基于37个线上任务实测,揭示四款主流工具在go-zero、gin、grpc-gateway 阅读详情

相关推荐

Go基础:一文掌握Go语言泛型的使用

Go 1.18引入泛型是Go语言的重大更新,支持类型参数、约束等概念,允许编写处理多种类型的通用代码。泛型函数和结构体可减少重复代码,如通用求和函数、栈/队列实现等。实际应用中,泛型适合集合操作、数据结构和工具函数等场景,但需合理使用类型约束,避免过度泛化。结合接口使用可提升代码复用性,同时保持类型安全和可维护性。泛型显著提升了Go代码的灵活性和扩展性,是处理通用需求的强大工具。

数据知道的博客 5972

Go 1.18 泛型全面讲解:一篇讲清泛型的全部

GO语言1.18版本新增功能泛型原理

nihaihaoma的专栏 1万+

MFC界面库BCGControlBar v32.0 - 对话框、仪表盘控件升级

亲爱的BCGSoft用户,我们非常高兴地宣布BCGControlBar Professional for MFC和BCGSuite for MFCv32.0正式发布!新版本支持Windows 11、增强功能区简化模式、改进控件外观等,以及其他新功能和改进。需要最新版的可以点击这里【BCG下载】 BCGControlBar Pro for MFC v32.0正式版下载 对话框和表单 1. 添加了一个新的全局标志globalData.m_bAutoPrepareComboListStyles:如果您希望.

需要界面开发、IDE工具研发中文教程资料的小伙伴,记得私信我~ 1145

go语言基础之泛型

当我们编写的是操作 Go 语言定义的特殊容器类型(slice、map和chennel)的函数。如果函数具有包含这些类型的参数,并且函数的代码并不关心元素的类型,那么使用类型参数可能是有用的。例如:返回任何类型map中所有的key// MapKeys 返回m中所有key组成的切片return s。

liu289747235的专栏 4148

Minecraft Forge模组开发入门:从环境搭建到事件监听实战

事件驱动编程是一种基于事件和事件监听器的软件架构模式,其核心原理是通过事件总线实现组件间的松耦合通信。在游戏开发领域,这种模式能够有效处理玩家交互、状态变更等异步操作,具有高度的灵活性和可扩展性。Java作为面向对象编程语言,通过注解和反射机制为事件驱动提供了天然支持。Minecraft模组开发正是事件驱动编程的典型应用场景,开发者可以利用Forge框架提供的事件总线监听游戏内各种行为。本文以Minecraft Forge模组开发为例,详细讲解如何通过Gradle构建工具搭建开发环境,并实现自定义方块注册和

culi3182的博客 395

前导0预测(Leading-Zero Anticipator,LZA)

前导0预测(Leading-Zero Anticipator,LZA) 浮点加法在完成之后会进行尾数规格化移位,而在进行尾数加法时,可以使用前导0预测(Leading-Zero Anticipator,LZA)同时计算移位,前导0预测只发生在一个正数加上一个负数的情况下,电路图如图1所示。 图1 传统LZD算法和LZA算法 1. 基础算法 算法的目标是计算出加法结果序列左边连续0的数量,下文中对...

crw1111111的博客 7375

Go 1.18新特性——泛型

泛型是一种编程范式,它将类型参数化,可以用于编写灵活且可重用的函数或数据结构,这样我们就可以用自己的类型来代替那些被硬编码的类型。泛型的好处是可以在编译时期发现类型不匹配的错误,而不是在运行时期。

m0_54644067的博客 2661

HTTP 代理服务器的设计与实现

HTTP 代理服务器的设计与实现 首先当然是最重要的代码:github地址 1) 实验目的 熟悉并掌握 Socket 网络编程的过程与技术;深入理解 HTTP 协议,掌握 HTTP 代理服 务器的基本工作原理;掌握 HTTP 代理服务器设计与编程实现的基本技能。 2) 实验内容 基于 java 实现了基本功能与全部附加功能,并增加了 https 的支持 (1) 设计并实现一个基本 HTTP 代理服...

qq_42754642的博客 1887

一文了解Go泛型

泛型是一种编程语言的特性,允许在编写代码时不指定具体的数据类型,而在运行时动态确定。这种特性使得我们能够编写更加灵活、通用的代码,而不必为每种数据类型编写相似的逻辑。

weixin_53623989的博客 2587

TC3XX - MCAL知识点(三十五):Tasking编译器下,Tc3xx的MCAL代码如何使用多核,多核中断、多核任务、多核外设之间的MCAL配置与代码例程

文章用于记录在裸机情况下使用多核Tc387芯片,如何高效运行以及正确的代码、工程属性、链接文件配置等问题,相互结合、相互影响的地方,以示后续使用记录。

梦想技术家 960

yocto系列讲解[实战篇]54 - 添加Qt5和生成带Qt5的SDK

为了满足读者盆友想看yocto如何添加qt5的需求,今天就开始尝试添加meta-qt5

fulinux的博客 3868

golang 泛型_说好的 Go1.17 支持泛型又推迟了:给你 GopherCon2020 全套 PPT 安慰下

点击上方蓝色“polarisxu”关注我,设个星标,不会让你失望2020 年 11 月 10 日是 Go 开源 11 周年,Go 官方发表了一篇博文:《Eleven Years of Go[1]》,回顾了过去一年 Go 的发展,同时展望未来一年,将要做的事情。01 过去一年回顾过去一年,因为疫情,大家都很难。Go 的发展也多少有些影响,但依然有不少产出。首先是去年 11 月份发布了 go...

weixin_39589644的博客 5584

YOLOv11涨点改进| TGRS 2026 顶刊| 注意力改进篇| 引入MSEA多尺度边缘感知注意力,助力红外小目标检测、遥感目标检测、工业缺陷检测、图像去雨雾任务高效涨点

🔥本文提出了一种基于MSEA多尺度边缘感知注意力的YOLOv11改进模型,通过增强网络对边缘、纹理和细粒度信息的感知能力,显著提升复杂背景下的目标检测性能。MSEA模块采用多尺度空洞卷积提取上下文特征,并通过边缘监督和注意力融合机制强化目标边界信息。实验表明该方法在小目标、边界模糊目标和复杂纹理目标检测任务中表现优异,尤其在遥感、工业缺陷和红外检测等场景具有显著优势。文章详细介绍了MSEA的结构原理、核心代码实现、模块配置方法以及三种YOLOv11改进方案.

Ai缝合怪、助力小伙伴高效发论文 181

“能力越大,责任越大” - Go语言之父详解将于Go 1.18发布的Go泛型

Go语言之父在2020.11.9~11.13举行的全球最具影响力的Go语言技术大会GopherCon 2020上,Go语言之父之一的Robert Griesemer为全世界Gopher们...

TonyBai 5469

RuyiDify如何创建知识库API密钥:让程序安全访问知识库

知识库 API Key 是程序访问知识库的钥匙。创建它很简单,但真正重要的是知道它能做什么、应该放在哪里、不能暴露给谁。RuyiDify 讲这一步,不是为了让大家多记一个按钮,而是为了把知识库从“人工上传资料”推进到“程序化维护资料”。

未来已来,AI时代,学AI编程,做AI量化,就来大鹏AI教育。 133

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

2020年Go语言盘点:新冠大流行阻挡不了Go演进的步伐

2020,这一六十年一遇的庚子年的确“名不虚传”。在这一年发生了很多事,而最受瞩目的事情莫过于新冠疫情的全球大流行。疫情给全球的经济带来了近似毁灭性的打击,给人们的生命带来了极大威胁,给...

TonyBai 2377

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

醒醒吧,未来不会有 Go2 了!

大家好,我是煎鱼。马上春节了,节前最后一更。提前预祝大家春节快乐!本周末在学习的时候,看到 Go 团队大当家 Russ Cox(下称:rsc)在近期分享的《GopherCon 2022: Russ Cox - Compatibility: How Go Programs Keep Working[1]》,讲的是 Go 在兼容性方面的现有问题和思考,还埋了个新预期。如下图:他提出了一个新的 Slog...

EDDYCJY的博客 262

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

AI 还在写“老式 Go”?Alan Donovan 详解 Go 代码的现代化

因为在 AI 还在学习旧代码的时候,我们的工具已经准备好带领我们通向 Modern Go 的未来。Donovan 分享了一个令人深思的实验:他测试了当前最先进的“思考型”大模型,要求它们使用最新的 Go 特性编写代码。打破这个循环的唯一方法,就是大规模地更新现有的代码库,让 AI 学习到新的语料。这个看似简单的重构为例,展示了它在处理变量作用域、副作用顺序时遇到的 4 个极其隐蔽的 Bug。本文将带你深入这场演讲的核心,揭秘 Go 官方如何通过工具化手段,解决 AI 时代的“代码老化”问题。

TonyBai 1033

Go 语言技术大佬们在 Twitter 上打起了口水战

转载链接:https://zhuanlan.zhihu.com/p/41627929即将发布的Go 1.11将加入对go mod的支持,解决了go一直存在的依赖管理的短板...

shellquery的博客 218

【Go】泛型

Go1.17引入了泛型的特性,1.18正式开放泛型,本文介绍了Go语言泛型的基本语法,使用示例,以及简要的实现原理,帮助你了解Go的泛型。

陈戏猿 2682

go泛型使用方法

go1.18泛型最全使用方法1. 泛型是什么2. 泛型的简单使用2.1. 泛型示例2.2. 自定义泛型类型2.3. 调用带泛型的函数3. 自定义泛型类型的语法3.1. 内置的泛型类型any和comparable3.2. 声明一个自定义类型3.3. 泛型中的"~"符号是什么4. 泛型的进阶使用4.1. 泛型与结构体5. 泛型的限制或缺陷5.1 无法直接和switch配合使用 1. 泛型是什么 泛型生命周期只在编译期,旨在为程序员生成代码,减少重复代码的编写 在比较两个数的大小时,没有泛型的时候,仅仅只是传入

doublewe的博客 1万+

go 语言中的泛型

泛型(Generics)是一种编程思想,它允许在编写代码时使用未知的类型。泛型可以增加代码的灵活性和可复用性,同时还能提高代码的安全性和可读性。

个人博客,记录了本人学习的各种有趣的技术。 1282

Go泛型全面讲解:一篇讲清泛型的全部

💡 本文力求能让未接触过泛型编程的人也能较好理解Go的泛型,所以行文可能略显啰嗦。但是请相信我,看完这篇文章你能获得对Go泛型非常全面的了解

不诱于誉,不恐于诽,率道而行,端然正己。 2353

Go语言学习——泛型

基础类型不能只有类型形参// 错误,类型形参不能单独使用。

jiajixi的博客 1330

Go 泛型

下一个重大变化已经到来。Go 的 1.18 版本包括了类型参数的实现,也就是俗称的泛型。在本章中,我们将探讨人们为什么需要泛型,Go 的泛型

tearon的博客 8514
上一篇: Go 1.18 发布了,不用翻墙即可下载!!!
下一篇: 3月份跑步月报
飞雪无情
博客等级 码龄7年 233粉丝 211原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值