go 泛型
从1.18版本开始,Go添加了对泛型的支持,即类型参数 泛型函数 没有泛型的痛点 对于相近类型的操作,可能会写多个一模一样的函数 不停的类型转换 package main import
go 泛型
发布时间:2023-10-06 (2023-10-06)

从1.18版本开始,Go添加了对泛型的支持,即类型参数

泛型函数

没有泛型的痛点

  1. 对于相近类型的操作,可能会写多个一模一样的函数
  2. 不停的类型转换
package main

import "fmt"
// 遍历int切片
func PrintIntSlice(slice []int) {
  for _, v := range slice {
    fmt.Printf("%T  %v\n", v, v)
  }
}
// 遍历int64切片
func PrintInt64Slice(slice []int64) {
  for _, v := range slice {
    fmt.Printf("%T  %v\n", v, v)
  }
}
// int64切片转int切片
func Int64SliceToIntSlice(Int64Slice []int64) (IntSlice []int) {
  for _, v := range Int64Slice {
    IntSlice = append(IntSlice, int(v))
  }
  return
}

func main() {
  PrintIntSlice([]int{1, 2, 3, 4, 5})
  var int64Slice []int64 = []int64{4, 5, 7}
  PrintInt64Slice(int64Slice)

  var intSlice []int
  for _, v := range int64Slice {
    intSlice = append(intSlice, int(v))
  }
  PrintIntSlice(intSlice)

  PrintIntSlice(Int64SliceToIntSlice(int64Slice))

}

有了泛型函数,就很方便

package main

import "fmt"

// 泛型函数
func PrintSliceTypeSlice[T int | int64 | string](slice []T) {
  fmt.Printf("%T\n", slice)
  for _, v := range slice {
    fmt.Printf("%T  %v\n", v, v)
  }
}

func main() {

  PrintSliceTypeSlice([]int{1, 2, 3, 4, 5})
  PrintSliceTypeSlice([]int64{1, 2, 3, 4, 5})
  PrintSliceTypeSlice([]string{"hello"})
  
  // 标准写法
  PrintSliceTypeSlice[int]([]int{1, 2, 3, 4, 5})
  PrintSliceTypeSlice[int64]([]int64{1, 2, 3, 4, 5})
  PrintSliceTypeSlice[string]([]string{"hello"})

}

泛型切片

package main

import "fmt"

type mySlice[T int | string] []T

func printIntTypeSlice[T int | int64 | string](slice []T) {
  fmt.Printf("%T\n", slice)
  for _, v := range slice {
    fmt.Printf("%T  %v\n", v, v)
  }
}
func main() {
  v1 := mySlice[int]{1, 2, 3, 4, 5}
  printIntTypeSlice(v1)
  v2 := mySlice[string]{"hello"}
  printIntTypeSlice(v2)
}

泛型map

package main

import "fmt"

type myMap[K string | int, V any] map[K]V
type _User struct {
  Name string
}

func main() {
  m1 := myMap[string, string]{
    "key": "fengfeng",
  }
  fmt.Println(m1)
  m2 := myMap[int, _User]{
    0: _User{"枫枫"},
  }
  fmt.Println(m2)
}

泛型约束

约束参数

package main

import "fmt"

type NumStr interface {
  Num | Str
}

// ~的意思就是底层数据类型
type Num interface {
  ~int | ~int32 | ~int64 | ~uint8
}
type Str interface {
  string
}

type Status uint8

type mySlice1[T NumStr] []T

func main() {
  m1 := mySlice1[int]{1, 2, 3}
  fmt.Println(m1)
  m2 := mySlice1[int64]{1, 2, 3}
  fmt.Println(m2)
  m3 := mySlice1[string]{"hello"}
  fmt.Println(m3)
  m4 := mySlice1[Status]{1, 2, 3}
  fmt.Println(m4)
}

约束方法

package main

import (
  "fmt"
  "strconv"
)

type Price int

func (p Price) String() string {
  // int转数字
  return strconv.Itoa(int(p))
}

type Price2 string

func (p Price2) String() string {
  // int转数字
  return string(p)
}

type showPrice interface {
  ~int | ~string
  String() string
}

func showPriceFunc[T showPrice](p T) {
  fmt.Println(p.String())

}

func main() {
  var p1 Price = 12
  showPriceFunc(p1)
  var p2 Price2 = "56"
  showPriceFunc(p2)
}