Go by Example: Generics泛型

英文源地址
从Go1.18版本开始,Go增加了对泛型(也成为类型参数)的支持.

package main

import "fmt"

// MapKeys 作为泛型函数的一个示例, MapKeys接受任何类型的映射,并返回其键的一个切片
// 该函数有两个类型参数K和V
// K具有可比较的约束, 这意味着我们可以用==和!=操作符比较这种类型的值
// 这是Go语言中作为map的键的必需条件
// V具有any的约束, 这意味着它不受任何方式的限制(any时interface{}的别名, 代表任何数据)
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
}

// List 作为泛型类型的一个示例.List是具有任意类型值的单链表
type List[T any] struct {
	head, tail *element[T]
}

type element[T any] struct {
	next *element[T]
	val  T
}

// Push 我们在泛型类型上定义方法, 就像在常规类型上定义方法一样
// 但必须保留类型参数. 类型为List[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
	}
}

func (lst *List[T]) GetAll() []T {
	var elems []T
	for e := lst.head; e != nil; e = e.next {
		elems = append(elems, e.val)
	}
	return elems
}

func main() {
	var m = map[int]string{1: "2", 2: "4", 4: "8"}
	// 在调用泛型函数时, 我们通常可以依赖类型推断
	// 注意, 在调用MapKeys时, 我们不必指定K和V的类型-编译器会自动推断它们
	fmt.Println("keys:", MapKeys(m))

	// 尽管我们也可以明确地指定它们
	_ = MapKeys[int, string](m)

	lst := List[int]{}
	lst.Push(10)
	lst.Push(13)
	lst.Push(23)
	fmt.Println("list:", lst.GetAll())
}
$ go run generics.go
keys: [4 1 2]
list: [10 13 23]

下一讲将介绍:Errors错误

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值