什么是泛型
为什么要泛型,在Java中,我们如果要实现一个函数可以处理多种类型的参数,可以使用泛型,但是之前的Go是不支持泛型的。这一点一直是Go被诟病的地方,现在泛型来了。
泛型是在Go的1.18 版本出现的。也就是类型参数的实现(泛型)
简单的泛型实现:
package main
import "fmt"
func main() {
strs := []string{"simple", "complex"}
PrintArray(strs)
}
func PrintArray[T string | int](arr []T) {
for _, a := range arr {
fmt.Println(a)
}
}
这里的T就是用户传入的所有的类型,前面中括号中就是对于T类型的约束。
这里的T就是一个形式类型。实际类型是用户传入的值的类型。
package main
import "fmt"
func main() {
strs := []string{"simple", "complex"}
ints := []int{1, 2, 3}
PrintArray(strs)
PrintAny(ints)
}
func PrintArray[T string | int](arr []T) {
for _, a := range arr {
fmt.Println(a)
}
}
func PrintAny[T any](a T) {
fmt.Println(a)
}
any表示go里面所有的内置基本类型,等价于interface{}空接口
还有一个关键字是叫做comparable 表示go中所有内置的可以比较的类型,比如:int,uint,float ,bool,struct ,指针等一切可以比较的类型。
当然这里的struct不指所有的。
泛型加法函数:
package main
import "fmt"
func add[T int | float32 | float64 | uint](a T, b T) T {
return a + b
}
func main() {
a := 1
b := 2
fmt.Println(add(a, b))
}
泛型学习文章:
https://segmentfault.com/a/1190000041634906
泛型类型
观察下面这个例子
type s1 []int
var a s1 = []int{1,2,3}
var b s1 = []float32{1.2,2.3,4.4}//错误
这里定义了一个int切片,底层是[]int,就应该赋值是int类型的切片。
但是如果我们就是想要定义一个可以容纳float32或者是string的切片呢?
使用泛型:
type Slice[T int|float32|string] []T
这样就可以了
这样的定义就是一个泛型类型。
package main
import "fmt"
func main() {
type Slice[T int | float32 | string] []T
var s1 Slice[int] = []int{1, 2, 3, 4}
var s2 Slice[string] = []string{"simple", "complex"}
fmt.Println(s1, s2)
泛型函数与方法
package main
import "fmt"
type MySlice[T int | float32] []T
func (s MySlice[T]) sum() T {
var sum T
for _, i := range s {
sum += i
}
return sum
}
func main() {
var s MySlice[int] = []int{1, 2, 3, 4, 5}
fmt.Println(s.sum())
var f MySlice[float32] = []float32{1.1, 2.2, 3.3, 4.2, 5.2, 6.1}
fmt.Println(f.sum())
}
自定义泛型类型
如果类型太多怎么办呢?这时候我们就可以自定义泛型类型
type Myint interface{
int|int8|int16|int32|int64
}
func GetMaxNum[T Myint](a,b T) T {
if a>b{
return a
}
return b
}
package main
import "fmt"
type Myint interface {
int | int32 | int16 | int64
}
func GetMaxNum[T Myint](a, b T) T {
if a > b {
return a
}
return b
}
func main() {
var (
a = 10
b = 20
)
fmt.Println(GetMaxNum(a, b))
}