[Go]泛型

[Go]泛型

使用方法

下面展示一下 go 泛型的基本使用方法

package main

import "fmt"

func main() {
	fmt.Printf("%v",Age[int](12))
}

func Age[T any](t T) T{
	return t
}

这是函数使用泛型的写法,当函数使用泛型的时候,需要在变量前使用中括号标注泛型的具体约束,然后后面才能使用这个泛型类型,使用泛型函数的时候,中括号是可以省略的 Age(12) 系统会自动推算泛型的具体实现。顺便说一下,泛型类型使用 %v 作为占位符,也就是默认的类型,泛型类型无法进行断言。

当然了,我么也可以不用 any,自定义一个约束

package main

import "fmt"

func main() {
	Age[int](12)
}
type st interface{
  int | string
}
func Age[T st](t T) {
	fmt.Println((t))
}

看完了在函数内的泛型,我们在看一下在方法中如何使用泛型

package main

import "fmt"

func main() {
	new(Age[int]).Post(12)

	var dd DD[int]
	dd.TT(12)
}

type Age[T any] struct {
	I T
}

func (a *Age[T]) Post(t T) {
	fmt.Println(a.I, t)
}

type DD[T any] []T

func(dd *DD[T])TT(t T){
	fmt.Println(t,len(*dd))
}

在 age 结构体声明的时候,声明了一个泛型 T,在 struct 体内就可以使用这个 T,方法内部仅可以使用定义在这个结构体对象上的泛型

下面是一个错误案例

// ❌
func (a *Age[T])Post[B any](t T,b B) {
	fmt.Println(a.I, t)
} 
syntax error: method must have no type parameters

接下来我们看一下,如何使用有类型也有方法的泛型

package main

import "fmt"

func main() {
	var d DDD
	var i DDD
	d = 1
	i = 2
	io := AbsDifference[DDD](d, i)
	fmt.Println(io)
}

type DDD int

func (ddd DDD) Abs() DDD {
	return ddd + ddd
}

type NumericAbs[T any] interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64 |
		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
		~float32 | ~float64 |
		~complex64 | ~complex128
	Abs() T
}

// AbsDifference computes the absolute value of the difference of
// a and b, where the absolute value is determined by the Abs method.
func AbsDifference[T NumericAbs[T]](a, b T) T {
	d := a - b
	return d.Abs()
}

用例子学泛型

函数泛型 map-filter-reduce

package main

import (
	"fmt"
)

func main() {
	vM := Map[int]([]int{1, 2, 3, 4, 5}, func(i int) int {

		return i + i
	})
	fmt.Printf("map的结果是:%v", vM)
	vF := Filter[int]([]int{1, 2, 3, 4, 5}, func(t int) bool {
		if t > 2 {
			return true
		}
		return false
	})
	fmt.Printf("filter的结果是:%v", vF)
	vR := Reduce[Value, *Result]([]Value{
		{name: "tt", year: 1},
		{name: "bb", year: 2},
		{name: "7i", year: 3},
		{name: "8i", year: 4},
		{name: "u4i", year: 5},
		{name: "uei", year: 6},
		{name: "uwi", year: 7},
		{name: "uti", year: 8},
	}, &Result{}, func(r *Result, v Value) *Result {
		r.value = r.value + v.year
		return r
	})
	fmt.Println("reduce的结果是:", vR.value)

}

// Map:类似于洗菜,进去的菜和出来的菜不一样了所以需要两种种类
func Map[T1, T2 any](arr []T1, f func(T1) T2) []T2 {
	result := make([]T2, len(arr))
	for k, v := range arr {
		result[k] = f(v)
	}
	return result
}

// Filter:类似于摘菜,进去的菜和出来的菜是一种,不过量减少了
func Filter[T any](arr []T, f func(T) bool) []T {
	var result []T
	for _, v := range arr {
		if f(v) {
			result = append(result, v)
		}
	}
	return result
}

// Reduce:类似于做菜,将菜做成一道料理,所以需要两种类型
func Reduce[T1, T2 any](arr []T1, zero T2, f func(T2, T1) T2) T2 {
	result := zero
	for _, v := range arr {
		result = f(result, v)
	}
	return result
}

type Value struct {
	name string
	year int
}
type Result struct {
	value int
}

在这里插入图片描述

例子二:方法上的泛型 sets

package main

import (
	"fmt"
)

func main() {

	// 这里 Sets的具体类型和Make的具体类型都是int,所以可以正常赋值
	var s Sets[int] = Make[int]()
	//
	s.Add(1)
	s.Add(2)
	fmt.Println(s)
	fmt.Println(s.Contains(3))
	fmt.Println(s.Len())
	s.Iterate(func(i int) {
		fmt.Println(i)
	})
	fmt.Println(s)
	s.Delete(2)
	fmt.Println(s)
}

// Sets 一个key  存储对象
type Sets[T comparable] map[T]struct{}

// Make 实例化一个map
func Make[D comparable]() Sets[D] {
	// 泛型就像一个管道一样,只要实例化的时候管子里的东西一致,那么就是一根管子
	return make(Sets[D])
}

// Add 向这个sets添加内容
func (s Sets[T]) Add(t T) {
	s[t] = struct{}{}
}

// delete ,从这个sets中删除内容
func (s Sets[T]) Delete(t T) {
	delete(s, t)
}

//  Contains 播报t是否属于这个sets
func (s Sets[T]) Contains(t T) bool {
	_, ok := s[t]
	return ok
}

//Len sets拥有的长度

func (s Sets[T]) Len() int {
	return len(s)
}

// Iterate 迭代器,并且给予每个元素功能

func (s Sets[T]) Iterate(f func(T)) {
	for k := range s {
		f(k)
	}
}

在这里插入图片描述

例子三:外部定义的约束 实现一个sort接口类型

package main

import "fmt"

func main() {
	fmt.Println("Hello, 世界")
}
// ~ 代表只要底层满足这些类型也可以算满足约束
type Ordered interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uintptr |
		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 |
		~float32 | ~float64 | ~string
}
type orderedSlice[T Ordered] []T

func (s orderedSlice[T]) Len() int           { return len(s) }
func (s orderedSlice[T]) Less(i, j int) bool { return s[i] < s[j] }
func (s orderedSlice[T]) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
func OrderedSlice[T Ordered](s []T) {
	sort.Sort(orderedSlice[T](s))
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值