前情提要

美国时间2022年3月15日,Go核心团队官宣了Go 1.18版本正式版的发布,其官博称之为“整个Go社区的一个巨大的里程碑”。在这个版本中,Go核心团队做了Go语言开源以来的最大一次语法特性变更——增加了对泛型(generics)的支持。

动手尝试

升级go 1.18

前往官网下载最新版本

Downloads - The Go Programming Language (google.cn)

需要卸载旧版本再安装新版本

修改VSCODE配置

VSCODE 可能会提示泛型语法只有 go 为 1.18 才可以使用

悬停红色波浪线,选择快速修复,执行提供的命令。重启VSCODE。

由于VSCODE go staticheck 会对go的泛型语法报黄色警告,我们需要修改 VSCODE 拓展设置,搜索 Lint Tool,将默认修改为 golint。

学习泛型

我们可以先参考 Go by Example 给出的例子

Go by Example 中文版: 范型 (gobyexample-cn.github.io)

  1. package main
  2. import "fmt"
  3. func MapKeys[K comparable, V any](m map[K]V) []K {
  4. r := make([]K, 0, len(m))
  5. for k := range m {
  6. r = append(r, k)
  7. }
  8. return r
  9. }

K,V 两种类型,要求K特征是能比较,V特征是全部,相当于 interface{}

  1. type List[T any] struct {
  2. head, tail *element[T]
  3. }
  4. type element[T any] struct {
  5. next *element[T]
  6. val T
  7. }

List 是一个 具有任意类型值的单链表。

  1. func (lst *List[T]) Push(v T) {
  2. if lst.tail == nil {
  3. lst.head = &element[T]{val: v}
  4. lst.tail = lst.head
  5. } else {
  6. lst.tail.next = &element[T]{val: v}
  7. lst.tail = lst.tail.next
  8. }
  9. }

调用范型函数的时候, 我们经常可以使用类型推断。 注意,当调用 MapKeys 的时候, 我们不需要为 KV 指定类型,编译器会自动进行类型推断

  1. fmt.Println("keys m:", MapKeys(m))

尝试泛型

我们经常需要程序对数据集合执行操作,例如选择满足给定条件的全部item,或通过自定义函数将全部item映射到一个新的集合。

在其它语言中,通常会使用泛型数据结构和算法。

  • Index、Include 方法参数为 comparable 类型,因为comparable特征的类型才可以进行比较
  • Any、All、Filter、Map 方法参数为 any 类型,使用了组合函数,可以传入一个方法。
  1. package main
  2. import (
  3. "fmt"
  4. "strings"
  5. )
  6. func Index[T comparable](vs []T, item T) int {
  7. for i, v := range vs {
  8. if v == item {
  9. return i
  10. }
  11. }
  12. return -1
  13. }
  14. func Include[T comparable](vs []T, item T) bool {
  15. return Index(vs, item) > 0
  16. }
  17. func Any[T any](vs []T, f func(T) bool) bool {
  18. for _, v := range vs {
  19. if f(v) {
  20. return true
  21. }
  22. }
  23. return false
  24. }
  25. func All[T any](vs []T, f func(T) bool) bool {
  26. for _, v := range vs {
  27. if !f(v) {
  28. return false
  29. }
  30. }
  31. return true
  32. }
  33. func Filter[T any](vs []T, f func(T) bool) []T {
  34. res := make([]T, 0)
  35. for _, v := range vs {
  36. if f(v) {
  37. res = append(res, v)
  38. }
  39. }
  40. return res
  41. }
  42. func Map[T any, K any](vs []T, f func(T) K) []K {
  43. res := make([]K, len(vs))
  44. for i, v := range vs {
  45. res[i] = f(v)
  46. }
  47. return res
  48. }
  49. func main() {
  50. fmt.Println("Golang 泛型的初步学习")
  51. ints := []int{10, 20, 30, 40, 50}
  52. intCompare := func(t int) bool {
  53. if t > 30 {
  54. return true
  55. }
  56. return false
  57. }
  58. fmt.Println(ints)
  59. fmt.Println("查找20下标", Index(ints, 20))
  60. fmt.Println("是否存在100", Include(ints, 100))
  61. fmt.Println("至少有一个大于30", Any(ints, intCompare))
  62. fmt.Println("全部大于30", All(ints, intCompare))
  63. fmt.Println("筛选大于30", Filter(ints, intCompare))
  64. fmt.Println("放大一倍", Map(ints, func(t int) int { return t * 2 }))
  65. textCompare := func(t string) bool {
  66. if len(t) > 5 {
  67. return true
  68. }
  69. return false
  70. }
  71. fruits := []string{"Apple", "Banana", "Orange"}
  72. fmt.Println("查找Orange下标", Index(fruits, "Orange"))
  73. fmt.Println("是否存在Apple", Include(fruits, "Apple"))
  74. fmt.Println("至少有一个元素长度大于5", Any(fruits, textCompare))
  75. fmt.Println("全部元素长度大于5", All(fruits, textCompare))
  76. fmt.Println("筛选长度大于5", Filter(fruits, textCompare))
  77. fmt.Println("每个元素重复一遍", Map(fruits, func(t string) string { return strings.Repeat(t, 2) }))
  78. newS := Map(fruits, func(t string) string { return strings.Repeat(t, 2) })
  79. fmt.Printf("%p %p", fruits, newS)
  80. }

Golang 泛型的简单使用的更多相关文章

  1. golang实现的简单优先队列

    下面是golang实现的简单优先队列,参考信息可以查看https://golang.org/pkg/container/heap/或者https://golang.google.cn/pkg/cont ...

  2. TODO:Golang UDP连接简单测试慎用Deadline

    TODO:Golang UDP连接简单测试慎用Deadline UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interco ...

  3. java 泛型的简单使用

    effecttive java一直推荐使用泛型,简单的看了一下泛型的使用 package cn.com.fzk; import java.util.ArrayList; import java.uti ...

  4. 数据结构和算法(Golang实现)(1)简单入门Golang-前言

    数据结构和算法在计算机科学里,有非常重要的地位.此系列文章尝试使用 Golang 编程语言来实现各种数据结构和算法,并且适当进行算法分析. 我们会先简单学习一下Golang,然后进入计算机程序世界的第 ...

  5. 数据结构和算法(Golang实现)(2)简单入门Golang-包、变量和函数

    包.变量和函数 一.举个例子 现在我们来建立一个完整的程序main.go: // Golang程序入口的包名必须为 main package main // import "golang&q ...

  6. 数据结构和算法(Golang实现)(3)简单入门Golang-流程控制语句

    流程控制语句 计算机编程语言中,流程控制语句很重要,可以让机器知道什么时候做什么事,做几次.主要有条件和循环语句. Golang只有一种循环:for,只有一种判断:if,还有一种特殊的switch条件 ...

  7. 数据结构和算法(Golang实现)(4)简单入门Golang-结构体和方法

    结构体和方法 一.值,指针和引用 我们现在有一段程序: package main import "fmt" func main() { // a,b 是一个值 a := 5 b : ...

  8. 数据结构和算法(Golang实现)(5)简单入门Golang-接口

    接口 在Golang世界中,有一种叫interface的东西,很是神奇. 一.数据类型 interface{} 如果你事前并不知道变量是哪种数据类型,不知道它是整数还是字符串,但是你还是想要使用它. ...

  9. 数据结构和算法(Golang实现)(6)简单入门Golang-并发、协程和信道

    并发.协程和信道 Golang语言提供了go关键字,以及名为chan的数据类型,以及一些标准库的并发锁等,我们将会简单介绍一下并发的一些概念,然后学习这些Golang特征知识. 一.并发介绍 我们写程 ...

随机推荐

  1. python学习之matplotlib实战

    import numpy as np def main(): # print("hello") # line import matplotlib.pyplot as plt x = ...

  2. 解决Ubuntu虚拟机占用空间与实际空间不符问题

    1.背景 右键点击Windows中的Ubuntu虚拟机文件夹,发现它占用Windows磁盘空间大小140GB: 然后进入Ubuntu,输入 df -hl 可以算出实际占用空间也大约为140GB.在Ub ...

  3. 6月27日 ajax

    AJAX准备知识:JSON 什么是 JSON ? JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation) JSON 是轻量级的文本数据交换格式 JS ...

  4. 6月4日 python学习总结 装饰器复习

    1.  装饰器的原理以及为什么要使用装饰器 在代码运行期间动态增加功能的方式,称之为"装饰器"(Decorator). 在不影响原代码结构的情况下为其添加功能 2.  装饰器的基本 ...

  5. GO后端开发+VUE实列

    因为我是从java转到go,代码结构跟我之前用java的很像 在这里只浅显的实战运用,没有过多理论讲解 工作环境:IDE:Goland , Go 1.17.7 框架 Gin+Gorm ,前端VUE 这 ...

  6. EasyUI 之datagrid 使用 【DataGrid属性解释】

    可选的参数 DataGrid 属性 覆写了 $.fn.datagrid.defaults. 参数名 类型 描述 默认值 title string Datagrid面板的标题 null iconCls ...

  7. 网络编程-Python的socket库

    一.网络连接经常用到的函数 sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)参数一:地址簇 socket.AF_INET IPv4(默认) ...

  8. MM32F0140的复位脚nRST复用成普通GPIO PA10功能

    目录: 1.MM32F0020简介 2.MM32F0020的复位脚nRST和PA10的说明 3.MM32F0020的选项字节说明 4.MM32F0020的FLASH_OBR选项字节寄存器说明 5.MM ...

  9. 模糊查询like语句该怎么写?

    第1种:在Java代码中添加sql通配符. string wildcardname = "%smi%"; list<name> names = mapper.selec ...

  10. mysql 的INNODB引擎和MYISAM引擎的区别、索引相关

    两个引擎都是使用B+tree 数据结构作为索引 不同点: 1.INNODB的主键必须要有,同时也是聚集索引,INNODB的数据文件本身就是索引文件:而MYISAM则是存储了数据的地址 2.INNODB ...