Go泛型草案设计简明指南

平台开发 360云计算

女主宣言

今天小编为大家分享一篇关于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 T    return 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中的泛型进行任何单一设计选择,背后都有很多理由。如果有兴趣深入研究该主题,可以查阅官方设计草案文档。如果有什么疑问或建议,可以在下方留言。

来源:https://www.icode9.com/content-4-897951.html

(0)

相关推荐

  • 如何使用 Go 中的函数类型 (function types)?

    函数类型(function types)是一种很特殊的类型,它表示着所有拥有同样的入参类型和返回值类型的函数集合. 如下这一行代码,定义了一个名叫 Greeting 的函数类型 type Greeti ...

  • Golang 类型断言 vs 类型转换

    这是一篇译文,原文出处:https://www.sohamkamani.com/golang/type-assertions-vs-type-conversions/. 在Go中,类型断言和类型转换是 ...

  • Go 学习笔记(31)— 字符串 string、字符 rune、字节 byte、UTF

    Go 学习笔记(31)— 字符串 string、字符 rune、字节 byte、UTF

  • Go 专栏|错误处理:defer,panic 和 recover

    最近校招又开始了,我也接到了一些面试工作,当我问「你觉得自己有什么优势」时,十个人里有八个的回答里会有一条「精力充沛,能加班」. 怪不得国家都给认证了:新生代农民工.合着我们这根本就不是什么脑力劳动者 ...

  • 包容性设计实践指南:重新定义用户,设计更友好易用的 APP

    了解包容性设计如何赢得人心和创造商业价值是一个非常个人化的旅程.作者通过医疗保健领域应用的实践案例说明了包容性设计的重要性.引导设计师思考如何重新定义用户概念,从而创建更具吸引力的客户渠道,并在社会中 ...

  • 产品结构设计·导光柱设计知识指南

    产品结构设计&#183;导光柱设计知识指南

  • 一份关于代码重构的简明指南

    [编者按]重构是一种对软件进行修改的行为,但它并不改变软件的功能特征,而是通过让软件程序更清晰,更简洁和更条理来改进软件的质量. 作者 | Alex Omeyer 译者 | 弯月 @CSDN(ID:C ...

  • 营养设计完全指南之常量营养素

    这是该金字塔系列第二篇文章,如果还没有看第一篇的读者们,请先在我昨天的推送中去查阅. 当我们谈论到常量营养素时,我们通常指的是:碳水化合物,蛋白质,脂肪.你可能听说过能量平衡决定了体重是增还是减,那营 ...

  • SMT钢网开孔设计优化指南

    SMT表面贴装技术作为现代电子信息产品制造业的核心技术,是当代电子信息制造产业十大最具生命力的技术之一! SMT锡膏印刷模板(stencil)又称SMT漏板.SMT网版.SMT钢网,它是用来定量分配锡 ...

  • 「大屏设计开发指南」实例讲解超大屏设计,附教程和素材

    同样使用FineReport开发大屏,为何我做出来的可视化效果总是达不到要求?是因为天生没有审美天赋吗? 其实,大屏模板开发只要掌握好设计技巧,普通的开发人员也能作出设计师级别的可视化效果,大师兄特地 ...

  • 施工总平面规划设计实施指南

    施工总平面规划设计实施指南

  • 干货 | 关于DC-DC转换器的选型及设计详细指南

    DC/DC转换器的规格说明 板载DC-DC转换器的规格是重要且详细的过程.选型正确后,它会产生符合所有应用的经济高效的解决方案.错误选择转换器会导致成本过高,或者不适合该应用.本常见问题解答将介绍板载 ...

  • 营养设计完全指南之营养时机与补剂

    这篇文章将会是这个系列的最后一篇,在这之前我们先回忆一下之前都讨论过哪些问题. 我们讲到了卡路里,能量平衡是体重改变的核心因素:我们讲到了常量营养素:蛋白质.脂肪.碳水化合物,以及如何去基于你的目标去 ...