基本语法
// 泛型函数
func 函数名[T 约束](参数 T) T {
// 函数体
}
// 泛型结构体
type 结构体名[T 约束] struct {
字段 T
}
关键概念
== 和 != 操作为什么要用泛型?
// 传统方式:为每种类型写重复代码
func MaxInt(a, b int) int {
if a > b { return a }
return b
}
func MaxFloat(a, b float64) float64 {
if a > b { return a }
return b
}
// 泛型方式:一个函数搞定
func Max[T cmp.Ordered](a, b T) T {
if a > b { return a }
return b
}
基础泛型函数
package main
import "fmt"
// 任何类型都可以
func PrintSlice[T any](s []T) {
for _, v := range s {
fmt.Print(v, " ")
}
fmt.Println()
}
// 可比较的类型
func FindIndex[T comparable](slice []T, target T) int {
for i, v := range slice {
if v == target {
return i
}
}
return -1
}
// 使用示例
func main() {
// 整数切片
intSlice := []int{1, 2, 3, 4, 5}
PrintSlice(intSlice)
fmt.Println("索引:", FindIndex(intSlice, 3))
// 字符串切片
strSlice := []string{"apple", "banana", "cherry"}
PrintSlice(strSlice)
fmt.Println("索引:", FindIndex(strSlice, "banana"))
// 自动类型推断
fmt.Println("最大值:", Max(10, 20))
fmt.Println("最大值:", Max(3.14, 2.71))
}
自定义类型约束
package main
import (
"fmt"
"strings"
)
// 自定义约束:要求类型支持String()方法
type Stringer interface {
String() string
}
// 数值类型约束
type Number interface {
int | int8 | int16 | int32 | int64 |
uint | uint8 | uint16 | uint32 | uint64 |
float32 | float64
}
// 使用自定义约束的函数
func PrintAll[T Stringer](items []T) {
for _, item := range items {
fmt.Println(item.String())
}
}
// 数值运算
func Sum[T Number](numbers []T) T {
var sum T
for _, num := range numbers {
sum += num
}
return sum
}
func Average[T Number](numbers []T) float64 {
if len(numbers) == 0 {
return 0
}
sum := Sum(numbers)
return float64(sum) / float64(len(numbers))
}
// 实现Stringer接口的类型
type Person struct {
Name string
Age int
}
func (p Person) String() string {
return fmt.Sprintf("%s (%d岁)", p.Name, p.Age)
}
type Product struct {
Name string
Price float64
}
func (p Product) String() string {
return fmt.Sprintf("%s - ¥%.2f", p.Name, p.Price)
}
// 使用示例
func main() {
// 使用Stringer约束
people := []Person{
{"张三", 25},
{"李四", 30},
}
PrintAll(people)
products := []Product{
{"手机", 2999.99},
{"电脑", 5999.50},
}
PrintAll(products)
// 使用数值约束
ints := []int{1, 2, 3, 4, 5}
floats := []float64{1.1, 2.2, 3.3, 4.4, 5.5}
fmt.Println("整数和:", Sum(ints))
fmt.Println("浮点数和:", Sum(floats))
fmt.Println("整数平均值:", Average(ints))
fmt.Println("浮点数平均值:", Average(floats))
}
实用工具函数
package main
import "fmt"
// 映射函数:将切片中的每个元素转换为另一种类型
func Map[T, U any](slice []T, f func(T) U) []U {
result := make([]U, len(slice))
for i, v := range slice {
result[i] = f(v)
}
return result
}
// 过滤函数:过滤出满足条件的元素
func Filter[T any](slice []T, f func(T) bool) []T {
var result []T
for _, v := range slice {
if f(v) {
result = append(result, v)
}
}
return result
}
// 归约函数:将切片归约为单个值
func Reduce[T, U any](slice []T, initial U, f func(U, T) U) U {
result := initial
for _, v := range slice {
result = f(result, v)
}
return result
}
// 包含判断
func Contains[T comparable](slice []T, target T) bool {
for _, v := range slice {
if v == target {
return true
}
}
return false
}
// 去重
func Unique[T comparable](slice []T) []T {
seen := make(map[T]bool)
var result []T
for _, v := range slice {
if !seen[v] {
seen[v] = true
result = append(result, v)
}
}
return result
}
// 使用示例
func main() {
numbers := []int{1, 2, 3, 4, 5, 2, 3, 4}
// 映射:将数字转换为字符串
strings := Map(numbers, func(n int) string {
return fmt.Sprintf("数字%d", n)
})
fmt.Println("映射结果:", strings)
// 过滤:只保留偶数
evens := Filter(numbers, func(n int) bool {
return n%2 == 0
})
fmt.Println("偶数:", evens)
// 归约:求和
sum := Reduce(numbers, 0, func(acc, n int) int {
return acc + n
})
fmt.Println("总和:", sum)
// 包含判断
fmt.Println("包含3:", Contains(numbers, 3))
fmt.Println("包含10:", Contains(numbers, 10))
// 去重
uniqueNumbers := Unique(numbers)
fmt.Println("去重后:", uniqueNumbers)
}
泛型结构体
// 泛型键值对
type Pair[K comparable, V any] struct {
Key K
Value V
}
// 使用示例
func main() {
// 字符串-整数对
pair1 := Pair[string, int]{"age", 25}
// 整数-字符串对
pair2 := Pair[int, string]{1, "one"}
fmt.Printf("对1: %s=%d\n", pair1.Key, pair1.Value)
fmt.Printf("对2: %d=%s\n", pair2.Key, pair2.Value)
}
[T 约束]、any、comparable、自定义约束