女主宣言

今天小编为大家分享一篇关于Golang泛型提案的最新设计草案。涉及有关为何做出某些决策的详细信息,实施细节等。希望能对大家有所帮助。

PS:丰富的一线技术、多元化的表现形式,尽在“360云计算”,点关注哦!

最近,go团队宣布了针对其go泛型提案的最新设计草案。涉及有关为何做出某些决策的详细信息,实施细节等。

因为整个草案设计内容太多了,所以本文中,我们的目标是总结即将进行的主要更改。

我们将提供一些代码片段来演示主要功能。

1

泛型函数中的类型约束

不受类型参数限制的通用函数:

// package decls, imports...func arrayOf(type T)(elems ...T) []T {arr := []T{}for _, el := range elems {arr = append(arr, el)}return arr
}func main() {strs := arrayOf("one", "two", "three", "four", "five")fmt.Println(strs)nums := arrayOf(1, 2, 3, 4, 5)fmt.Println(nums)
}

要对通用类型添加约束,可以要求实现给定的接口:

// package decls, imports...// Person, who implements fmt.Stringer...func join(type T fmt.Stringer)(tokens []T, delim string) string {res := ""for _, token := range tokens {if res != "" {res += delim}res += token.String()}return res
}func main() {joined := join([]Person{Person{"Mike", "Jordan"}, Person{"Dave", "Stevens"}, Person{"John", "Doe"}}, ", ")fmt.Println(joined)
}

要指定多个类型参数,用逗号分隔:

// package decls, imports...func mapAll(type T, R)(arr []T, mapFunc func(T) R) []R {res := []R{}for _, el := range arr {res = append(res, mapFunc(el))}return res
}func main() {strs := mapAll([]int{1, 2, 3}, func(n int) string {return strconv.Itoa(n)})fmt.Println(strs)
}

对多个类型参数的约束,与编写函数参数类型相同的方式写入:

// package decls, imports...// Person & Animal structs, which implement fmt.Stringer...func Concat(type T1, T2 fmt.Stringer)(f T1, s T2, delim string) string {return f.String() + delim + s.String()
}func main() {res := Concat(Person{"John", "Doe"}, Animal{"Dog", "Richie"}, " loves his ")fmt.Println(res)
}

以下是为两个参数指定不同类型的方法:

// package decls, imports...// Hooman & Pet interfaces...
// Person & Dog structs...func PlayAround(type H Hooman, P Pet)(human H, pet P) {fmt.Println("The human says:", human.Speak())fmt.Println("And the pet responds:", pet.ProduceSound())
}func main() {PlayAround(Person{}, Dog{})
}

2

类型列表及可比较

可以基于一组受支持的类型来约束它们,而不是基于一组方法来约束类型。例如,可以指定接受通用类型,该通用类型只能是int或long。

这能够 利用“小于”,“大于”之类的运算符,仅适用于Go中的基本类型:

// package decls, imports...// Ordered is a type constraint that matches any ordered type.
// An ordered type is one that supports the <, <=, >, and >= operators.
type Ordered interface {type int, int8, int16, int32, int64,uint, uint8, uint16, uint32, uint64, uintptr,float32, float64,string
}func Max(type T Ordered)(elems []T) T {if len(elems) == 0 {var zero Treturn zero}max := elems[0]for _, el := range elems {if el > max {max = el}}return max
}func main() {res := Max([]int{1, 5, 3, 10, 4})fmt.Println(res)
}

还具有一个称为“comparable”的现成约束,该约束类型与支持==和!=运算符的约束类型相同。

// package decls, imports...func Contains(type T comparable)(elems []T, target T) bool {for _, elem := range elems {if elem == target {return true}}return false
}func main() {fmt.Println(Contains([]int{1, 2, 3, 4, 5}, 4))
}

使用这些构造的接口-类型列表和/或类似列表只能用作类型约束,而不能用作函数参数。

3

通用类型

可以使用泛型类型定义结构。一旦指定了类型声明,就无需为该类型的所有函数指定类型:

// package decls, imports...type Stack(type T) struct {buffer []T
}func (v *Stack(T)) Push(elem T) {v.buffer = append(v.buffer, elem)
}func (v *Stack(T)) Pop() T {res := v.buffer[len(v.buffer)-1]v.buffer = v.buffer[:len(v.buffer)-1]return res
}func main() {st := &Stack(int){}st.Push(1)st.Push(2)  st.Push(3)fmt.Println(st.Pop())fmt.Println(st.Pop())fmt.Println(st.Pop())
}

也可以在接口中执行此操作。当类型约束依赖于自身时,这尤其有用。

例如。有一个T的类型约束,它需要一个Equal方法,该方法接受一个T参数:

// package decls, imports...// Person, who implements Equaler...type Equaler(type T) interface {Equal(other T) bool
}func Contains(type T Equaler)(elems []T, target T) bool {for _, elem := range elems {if elem.Equal(target) {return true}}return false
}func main() {people := []Person{Person{"Dave"}, Person{"Bob"}, Person{"Steve"}}fmt.Println(Contains(people, Person{"Dave"}))
}

如果需要指定具有状态修改功能的类型参数(例如,setter),则可以指定指针类型约束:

// package decls, imports...type Setter interface {Set(string)
}type Settable int// Set sets the value of *p from a string.
func (p *Settable) Set(s string) {i, _ := strconv.Atoi(s)*p = Settable(i)
}func FromStrings(type *T Setter)(s []string) []T {result := make([]T, len(s))for i, v := range s {// result[i] is an addressable value of type T,// so it's OK to call Set.result[i].Set(v)}    return result
}func main() {nums := FromStrings(Settable)([]string{"1", "2", "3"})fmt.Println(nums)
}

注意,上面的示例如何要求明确指定将在函数中使用的类型– FromStrings(Settable)…

这是因为只要类型不作为函数参数出现,编译代码后,编译器就无法推断实际类型。因此,需要明确指定它。

总结

本文的目的是简洁明了。希望它可以帮助大家快速了解最新的泛型草案设计。

但是,围绕Go中的泛型进行任何单一设计选择,背后都有很多理由。如果有兴趣深入研究该主题,可以查阅官方设计草案文档。如果有什么疑问或建议,可以在下方留言。

360云计算

由360云平台团队打造的技术分享公众号,内容涉及数据库、大数据、微服务、容器、AIOps、IoT等众多技术领域,通过夯实的技术积累和丰富的一线实战经验,为你带来最有料的技术分享

Go泛型草案设计简明指南相关推荐

  1. [201206][UML 精粹][标准对象建模语言简明指南][第3版][Martin Fowler][著]

    [201206][UML 精粹][标准对象建模语言简明指南][第3版][Martin Fowler][著][UMLChina][潘加宇][译] 第 1 章 简介 1.1 UML 是什么 1.2 使用 ...

  2. ASIC设计-终极指南

    ASIC设计-终极指南 ASIC Design – The Ultimate Guide ASIC设计-终极指南 ASICs代表特定于应用的集成电路,指的是针对特定应用而设计的半导体解决方案,与其他解 ...

  3. UE4风格化场景设计入门指南 Stylized Station – The Environment Artist’s Survival Kit

    持续时间13h 1920X1080 .ts 包含项目文件 大小解压后:4.9G 语言:英语+中文字幕(人工校对) 标题:风格化的车站--环境艺术家的生存工具包 信息: 环境艺术很难. 尤其是作为初学者 ...

  4. 交互设计实用指南系列 – 我们眼中的交互设计

    交互设计(Interaction Design, 缩写 IxD 或者 IaD),是定义.设计人造系统的行为的设计领域.人造物,即人工制成物品,例如,软件.移动设备.人造环境.服务.可佩带装置以及系统的 ...

  5. git - 简明指南

    助你入门 git 的简明指南,木有高深内容 ;) Tweet 作者:罗杰·杜德勒  感谢:@tfnico, @fhd 和 Namics 其他语言 english, deutsch, español,  ...

  6. 从零开始来看一下Java泛型的设计

    引言 泛型是Java中一个非常重要的知识点,在Java集合类框架中泛型被广泛应用.本文我们将从零开始来看一下Java泛型的设计,将会涉及到通配符处理,以及让人苦恼的类型擦除. 泛型基础 泛型类 我们首 ...

  7. 特别引人注目的头像_设计样式指南:构建引人注目的产品的要素

    特别引人注目的头像 If you look at companies like Dropbox, Google, and Twitter you'll notice that they each ha ...

  8. 小厂B端产品啥都干——B端表格设计入门指南(上)

    前言 众所周知,表格是一种可以清晰.全面.高效地将数据展示出来的组件,作为B端产品,表格一定是产品设计工作中接触最多的组件,今天我就以一个小场景来说说B端表格的应该如何入门. 关于本系列文章,有几点需 ...

  9. 小厂B端产品啥都干——B端表格设计入门指南(中)

    前言 书接上回,上一篇B端表格指南向大家展示了一些常见的表格样式,在产品设计能力中,一个人的眼界往往决定了这个人的产品设计下限,所以我将常见表格样式的介绍放在了第一篇,那么第二篇将从底层思维上给大家提 ...

最新文章

  1. 计算机应用发展方向展望,我国计算机应用现状及展望.doc
  2. mysql获取后一天_MySQL根据某一Date值获取相关时间(前一天,后一天等)
  3. SAP S/4HANA使用ABAP获得生产订单的状态 1
  4. 如何使 WebAPI 自动生成漂亮又实用在线API文档
  5. deb 中标麒麟_「图」百度网盘Linux版放出deb包客户端:新增支持Ubuntu 18.04 LTS
  6. crtsiii型无砟轨道板_无砟轨道裂缝破损怎么修补
  7. POI读取word文件,(支持HSSF和XSSF两种方式)
  8. day22 java的枚举
  9. 多人操作sqlite3数据库冲突问题解决方法
  10. QAM调制原理_广播百科 QAM
  11. IDEA2020版本下载、安装
  12. pythonpdf识别文字_python 提取pdf文字
  13. B. Shashlik Cooking
  14. 苹果内购后台(java)验证订单
  15. IR-61|1895075-34-9|七甲川吲哚类花菁染料near-infrared fluorophore
  16. 元宇宙行业也有冬天!Meta将裁员数千人 小扎狠过马斯克
  17. pb文件转java 报:protoc did not exit cleanly. Review output for more information
  18. 有没有html做的平安夜页面或者圣诞节,送给同学的平安夜圣诞节祝福语
  19. Add User for Power Apps 给PowerApps 添加账号
  20. 2021年高处作业登高架设证上机考试题库

热门文章

  1. 烽火MAS短信服务器配置相关
  2. 将表数据生成SQL脚本的存储过程和工具
  3. MIX 2008与ASP.NET MVC框架的Road-Map
  4. 如何使用Alert 组件
  5. versions-maven-plugin插件批量修改版本号
  6. Eclipse远程调试Java代码的三种方法
  7. 【Linux】查看日志文件
  8. php处理ubb代码,过滤UBB代码的php类
  9. java 实现回收站功能,shell编程之实现windows回收站功能分享
  10. python xampp mysql_php xampp mysql