前情提要

美国时间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)

package main

import "fmt"

func MapKeys[K comparable, V any](m map[K]V) []K {
r := make([]K, 0, len(m))
for k := range m {
r = append(r, k)
}
return r
}

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

type List[T any] struct {
head, tail *element[T]
} type element[T any] struct {
next *element[T]
val T
}

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

func (lst *List[T]) Push(v T) {
if lst.tail == nil {
lst.head = &element[T]{val: v}
lst.tail = lst.head
} else {
lst.tail.next = &element[T]{val: v}
lst.tail = lst.tail.next
}
}

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

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

尝试泛型

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

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

  • Index、Include 方法参数为 comparable 类型,因为comparable特征的类型才可以进行比较
  • Any、All、Filter、Map 方法参数为 any 类型,使用了组合函数,可以传入一个方法。
package main

import (
"fmt"
"strings"
) func Index[T comparable](vs []T, item T) int {
for i, v := range vs {
if v == item {
return i
}
}
return -1
} func Include[T comparable](vs []T, item T) bool {
return Index(vs, item) > 0
} func Any[T any](vs []T, f func(T) bool) bool {
for _, v := range vs {
if f(v) {
return true
}
}
return false
} func All[T any](vs []T, f func(T) bool) bool {
for _, v := range vs {
if !f(v) {
return false
}
}
return true
} func Filter[T any](vs []T, f func(T) bool) []T {
res := make([]T, 0)
for _, v := range vs {
if f(v) {
res = append(res, v)
}
}
return res
} func Map[T any, K any](vs []T, f func(T) K) []K {
res := make([]K, len(vs))
for i, v := range vs {
res[i] = f(v)
}
return res
} func main() {
fmt.Println("Golang 泛型的初步学习") ints := []int{10, 20, 30, 40, 50} intCompare := func(t int) bool {
if t > 30 {
return true
}
return false
}
fmt.Println(ints)
fmt.Println("查找20下标", Index(ints, 20))
fmt.Println("是否存在100", Include(ints, 100))
fmt.Println("至少有一个大于30", Any(ints, intCompare))
fmt.Println("全部大于30", All(ints, intCompare))
fmt.Println("筛选大于30", Filter(ints, intCompare))
fmt.Println("放大一倍", Map(ints, func(t int) int { return t * 2 })) textCompare := func(t string) bool {
if len(t) > 5 {
return true
}
return false
}
fruits := []string{"Apple", "Banana", "Orange"}
fmt.Println("查找Orange下标", Index(fruits, "Orange"))
fmt.Println("是否存在Apple", Include(fruits, "Apple"))
fmt.Println("至少有一个元素长度大于5", Any(fruits, textCompare))
fmt.Println("全部元素长度大于5", All(fruits, textCompare))
fmt.Println("筛选长度大于5", Filter(fruits, textCompare))
fmt.Println("每个元素重复一遍", Map(fruits, func(t string) string { return strings.Repeat(t, 2) })) newS := Map(fruits, func(t string) string { return strings.Repeat(t, 2) })
fmt.Printf("%p %p", fruits, newS)
}

最新文章

  1. Flex Builder读书笔记(一)
  2. C/C++中的abort、atexit、exit和_Exit
  3. 表空间、Schema和用户
  4. String的那点小事儿
  5. HashMap与HashTable联系与区别
  6. 使用Apache 的lib进行List、Set、数组之间的转换(转)
  7. 转 [教程] Unity3D中角色的动画脚本的编写(二)
  8. Linux下which、whereis、locate、find 命令查找文件
  9. Android 推送和统计最优轮循(心跳策略)探究实践
  10. 复写的Object常用方法
  11. python学习笔记(十 一)、GUI图形用户界面
  12. CentOS 7 Tomcat 8 9 基于APR库性能优化
  13. DAY03、基本数据类型和运算符
  14. 小学生都看得懂的C语言入门(2): 判别 循环的一些应用实例
  15. 042 spring boot在启动之后,自动关闭
  16. C#--WinForm项目主窗体设计
  17. ST表的原理及其实现
  18. 图片视频访问servlet(支持苹果视频断点续传)
  19. win10 uwp 重启软件
  20. 解决文字和text-decoration:underline下划线重叠问题

热门文章

  1. 基于SpringBoot实现自动装配返回属性
  2. 类型转换Java day8
  3. BUAA_C++算法板子积累_动态规划、图算法、计算几何、FFT
  4. switch 是否能作用在 byte 上,是否能作用在 long 上, 是否能作用在 String 上?
  5. JVM调优常用参数配置
  6. 解释 JDBC 抽象和 DAO 模块?
  7. 180度\360度sg90舵机的使用及代码程序
  8. (stm32f103学习总结)—GPIO结构
  9. AD学习总结
  10. 单例模式应用 | Shared_ptr引用计数管理器