Golang 泛型的简单使用
前情提要
美国时间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 的时候, 我们不需要为 K 和 V 指定类型,编译器会自动进行类型推断
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)
}

Golang 泛型的简单使用的更多相关文章
- golang实现的简单优先队列
下面是golang实现的简单优先队列,参考信息可以查看https://golang.org/pkg/container/heap/或者https://golang.google.cn/pkg/cont ...
- TODO:Golang UDP连接简单测试慎用Deadline
TODO:Golang UDP连接简单测试慎用Deadline UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interco ...
- java 泛型的简单使用
effecttive java一直推荐使用泛型,简单的看了一下泛型的使用 package cn.com.fzk; import java.util.ArrayList; import java.uti ...
- 数据结构和算法(Golang实现)(1)简单入门Golang-前言
数据结构和算法在计算机科学里,有非常重要的地位.此系列文章尝试使用 Golang 编程语言来实现各种数据结构和算法,并且适当进行算法分析. 我们会先简单学习一下Golang,然后进入计算机程序世界的第 ...
- 数据结构和算法(Golang实现)(2)简单入门Golang-包、变量和函数
包.变量和函数 一.举个例子 现在我们来建立一个完整的程序main.go: // Golang程序入口的包名必须为 main package main // import "golang&q ...
- 数据结构和算法(Golang实现)(3)简单入门Golang-流程控制语句
流程控制语句 计算机编程语言中,流程控制语句很重要,可以让机器知道什么时候做什么事,做几次.主要有条件和循环语句. Golang只有一种循环:for,只有一种判断:if,还有一种特殊的switch条件 ...
- 数据结构和算法(Golang实现)(4)简单入门Golang-结构体和方法
结构体和方法 一.值,指针和引用 我们现在有一段程序: package main import "fmt" func main() { // a,b 是一个值 a := 5 b : ...
- 数据结构和算法(Golang实现)(5)简单入门Golang-接口
接口 在Golang世界中,有一种叫interface的东西,很是神奇. 一.数据类型 interface{} 如果你事前并不知道变量是哪种数据类型,不知道它是整数还是字符串,但是你还是想要使用它. ...
- 数据结构和算法(Golang实现)(6)简单入门Golang-并发、协程和信道
并发.协程和信道 Golang语言提供了go关键字,以及名为chan的数据类型,以及一些标准库的并发锁等,我们将会简单介绍一下并发的一些概念,然后学习这些Golang特征知识. 一.并发介绍 我们写程 ...
随机推荐
- Docker 容器、镜像、日志相关操作
一. 容器操作 新建并启动 命令:docker run 查看容器 命令:docker ps 查看终止状态的容器 命令:docker ps -a 启动已终止容器 命令:docker start 终止容器 ...
- redis规范(实用)
redis功能强大,数据类型丰富,再快的系统,也经不住疯狂的滥用.通过禁用部分高风险功能,并挂上开发的枷锁,业务更能够以简洁.通用的思想去考虑问题,而不是绑定在某种实现上. Redis 根据不同的用途 ...
- Oracle视图(view)传参数教程
废话不多说,直接上例子! 创建包: create or replace package p_view_param is function set_param(num number) return nu ...
- Docker安装与基本命令
docker安装 Ubuntu 更新apt包索引 sudo apt-get update 更新apt包索引 sudo apt-get upgrade 安装docker sudo apt-get ins ...
- XML技术的作用?
XML技术用于数据存储.信息配置.数据交换三方面. 可以将数据存储在XML中,通过节点.元素内容.属性标示数据内容及关系. 可以使用XML很方便的做信息配置,软件的各种配置参数和对象关系都存贮在XML ...
- python 函数基础知识
1.函数返回的多个值会被组织成元组被返回,也可以用多个值来接收 2.调用函数时候,传入的参数叫实际参数,简称实参,定义函数的参数叫做形式参数,简称形参-- 位置参数 def mymax(x,y): a ...
- 解释Spring支持的几种bean的作用域?
Spring框架支持以下五种bean的作用域: singleton :bean在每个Spring ioc 容器中只有一个实例. prototype:一个bean的定义可以有多个实例. request: ...
- 什么是 CSRF 攻击?
CSRF 代表跨站请求伪造.这是一种攻击,迫使最终用户在当前通过身份验证的 Web 应用程序上执行不需要的操作.CSRF 攻击专门针对状态改变请求,而不是 数据窃取,因为攻击者无法查看对伪造请求的响应 ...
- SVG是什么?
SVG表示(scalable vector graphics)可缩放矢量图形.这是一个基于文本的图形语言,它可以绘制使用文本.线.点等的图形,因此可以轻巧又快速地渲染.
- SQLAlchemy 使用教程
前戏: 不用怀疑,你肯定用过Django中的orm,这个orm框架是django框架中自己封装的,在Django中配置和使用较为简单,但是并不适用于其他web框架,而今天说的sqlalchemy是 ...