0

0

Go1.18 泛型初探

Go语言进阶学习

Go语言进阶学习

发布时间:2023-07-24 15:00:40

|

994人浏览过

|

来源于Go语言进阶学习

转载

今天我们要实现的函数功能是:对 map 里所有的 value 求和。

非泛型函数

如果没有泛型该如何实现呢?因为 value 可能会有不同的类型,比如:int64、float64 等,没有泛型的话,针对不同类型需要通过不同的函数来实现,所以我们一般都会像下面这样实现:

func SumInts(m map[string]int64) int64 {
    var s int64
    for _, v := range m {
        s += v
    }
    return s
}

func SumFloats(m map[string]float64) float64 {
    var s float64
    for _, v := range m {
        s += v
    }
    return s
}

上面的代码,我们定义了两个函数:

1、SumInts() 计算 value 为 int64 类型的总和;2、SumFloats() 计算 value 为 float64 类型的总和;

上面函数只适用于 int64、float64 类型,那如果我们还想计算 int、float32 等,就得把上面的函数重新 copy 一份修改下类型。

这样做岂不是稍显麻烦,而且代码很臃肿,你还别说,之前标准包有很多类似的代码,比如标准库的 Sort 包(sort.go) 为了实现不同类型切片的排序,定义了 IntSlice、Float64Slice、StringSlice。

因为之前 Go 版本不支持泛型,只能这样实现,这也是最简单的一种方法。

有了泛型之后,针对不同类型 int64、float64,该如何实现一个函数就能计算出 value 的总和呢?

泛型函数

这一小节我们通过一个泛型函数实现既可以接收 value 为 int64 类型的 map 作为参数,也可以接收 value 为 float64 类型的 map 作为参数。

完整代码如下:

func Sum[K comparable, V int64 | float64](m map[K]V "K comparable, V int64 | float64") V {
 var s V
 for _, v := range m {
  s += v
 }
 return s
}

func main() {
 ints := map[string]int64{
  "first":  1,
  "second": 2,
 }
 fmt.Println(Sum[string, int64](ints "string, int64"))

 floats := map[string]float64{
  "first":  35.98,
  "second": 26.99,
 }
 fmt.Println(Sum[string, float64](floats "string, float64"))
}

上面的代码,我们定义了 Sum() 函数,它是一个泛型函数,可以看到与普通函数不同的是,在函数名与函数参数列表之间有一组方括号 [],方括号里有两个参数 K 和 V,Go 语言里称为类型参数,紧跟在 K、V 后面是类型限制,其中 comparable 是 Go 语言预声明的,表示任何能做 == 和 != 操作的类型。V 的类型限制是 int64、float64 其中的一种。函数参数是 m,类型是 map[K]V,返回类型是 V。

调用函数也与调用普通函数有点不同,在函数名与实参之间有一组方括号 [],指明了类型名称。比如第一次调用 Sum() 函数时,类型名称分别是 string、int64,那么在执行函数时,对应 K、V 的类型分别是 string 和 int64。

第二次调用该 Sum() 函数时,K、V 的类型分别是 string 和 float64。

通过泛型编程,我们就可以实现一个函数处理多种数据类型。

执行上面的代码输出:

3
62.97

相关专题

更多
c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

22

2026.01.23

c++空格相关教程合集
c++空格相关教程合集

本专题整合了c++空格相关教程,阅读专题下面的文章了解更多详细内容。

24

2026.01.23

yy漫画官方登录入口地址合集
yy漫画官方登录入口地址合集

本专题整合了yy漫画入口相关合集,阅读专题下面的文章了解更多详细内容。

99

2026.01.23

漫蛙最新入口地址汇总2026
漫蛙最新入口地址汇总2026

本专题整合了漫蛙最新入口地址大全,阅读专题下面的文章了解更多详细内容。

132

2026.01.23

C++ 高级模板编程与元编程
C++ 高级模板编程与元编程

本专题深入讲解 C++ 中的高级模板编程与元编程技术,涵盖模板特化、SFINAE、模板递归、类型萃取、编译时常量与计算、C++17 的折叠表达式与变长模板参数等。通过多个实际示例,帮助开发者掌握 如何利用 C++ 模板机制编写高效、可扩展的通用代码,并提升代码的灵活性与性能。

15

2026.01.23

php远程文件教程合集
php远程文件教程合集

本专题整合了php远程文件相关教程,阅读专题下面的文章了解更多详细内容。

65

2026.01.22

PHP后端开发相关内容汇总
PHP后端开发相关内容汇总

本专题整合了PHP后端开发相关内容,阅读专题下面的文章了解更多详细内容。

61

2026.01.22

php会话教程合集
php会话教程合集

本专题整合了php会话教程相关合集,阅读专题下面的文章了解更多详细内容。

63

2026.01.22

宝塔PHP8.4相关教程汇总
宝塔PHP8.4相关教程汇总

本专题整合了宝塔PHP8.4相关教程,阅读专题下面的文章了解更多详细内容。

33

2026.01.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 4.1万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号