泛型
前言
Go在1.18版本中正式带来泛型特性。
什么是泛型
泛型(Generic)是编程中的一种机制,允许类、接口和方法能够在定义时使用占位符来表示数据类型,从而使代码能够适应多种不同的数据类型,而无需重复编写相似的代码。泛型主要用于提高代码的复用性、可读性和安全性。泛型最常见的应用是在静态类型语言(如Java、C#、C++等)中,通过为类或方法定义参数化类型,可以在实例化时指定具体的类型。这意味着可以编写一次逻辑,然后在多个不同的数据类型上重复使用。
泛型的优点:
- 类型安全:通过指定类型参数,编译器可以在编译时检查类型是否匹配,减少运行时错误。
- 代码复用:可以编写更加通用的代码,而不必为每种数据类型编写重复的代码。
- 可读性和可维护性:减少代码冗余,提高可读性,代码的维护也变得更加容易。
泛型的声明
- 泛型切片
type Slice1 [T int|float64|string] []T
// 可以指代下面三种的切片类型
type SliceInt []int
type SliceFloat []float64
type SliceInt []string
- 泛型哈希表
type Map1 [KEY int|string, VALUE string| float64] map[KEY]VALUE
// 相当于
type Map2 map[int]string
type Map3 map[int]float64
type Map4 map[string]string
type Map5 map[string]float64
- 泛型结构体
type Struct1 [T string|int|float64] struct {
Title string
Content T
}
// 相当于
// 结构体
type Struct3 struct {
Title string
Content string
}
type Struct4 struct {
Title string
Content int
}
type Struct5 struct {
Title string
Content float64
}
- 泛型方法。下面的泛型方法可以灵活地对任意类型的 Data 进行加锁,并执行 f 函数
type Lockable[T any] struct {
mu sync.Mutex
data T
}
func (l *Lockable[T]) Do(f func(*T)) {
l.mu.Lock()
defer l.mu.Unlock()
f(&l.data)
}
- 泛型函数
// 函数 NoDiff 可以判断可变长度数组中的每一个元素是不是都是相同的。
func NoDiff[V comparable](vs ...V) bool {
if len(vs) == 0 {
return true
}
v := vs[0]
for _, x := range vs[1:] {
if v != x {
return false
}
}
return true
}
- 泛型接口
type MyInterface[T int | string] interface {
WriteOne(data T) T
ReadOne() T
}