ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Golang 泛型的简单使用

2022-03-29 19:33:18  阅读:251  来源: 互联网

标签:return fmt fruits Golang Println vs func 简单 泛型


前情提要

美国时间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。image-20220329184941851

学习泛型

我们可以先参考 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)
}

image-20220329185301322

标签:return,fmt,fruits,Golang,Println,vs,func,简单,泛型
来源: https://www.cnblogs.com/linxiaoxu/p/16072710.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有