Golang 泛型

前言

泛型是在Go 1.18版本中引入的,它允许编写可以在多种数据类型上工作的函数和数据类型。这样做可以增加代码的复用性并减少重复

使用

  1. 类型参数(Type Parameters): 你可以在函数或类型定义上声明类型参数,使其具有泛型性。类型参数被放在方括号中,并在函数签名或类型声明中使用

来看个例子:

package main

import "fmt"

// 定义一个泛型函数
func Print[T any](s []T) {
    for _, v := range s {
        fmt.Println(v)
    }
}

func main() {
    // 使用泛型函数打印不同类型的切片
    Print([]int{1, 2, 3})
    Print([]string{"hello", "world"})
}

Print 函数通过类型参数 T 来接受任意类型的切片。类型参数 T 被约束为 any,这意味着 T 可以是任何类型。然后我们可以传入不同类型的切片给 Print 函数

  1. 类型约束(Type Constraints): 类型参数可以有约束,用来限制可以传递给泛型的类型。这些约束是接口类型
type Number interface {
    int | float64
}

// Sum 将一个 Number 类型的切片中的所有元素相加
func Sum[T Number](s []T) T {
    var sum T
    for _, v := range s {
        sum += v
    }
    return sum
}

Sum 函数只接受实现了 Number 接口的类型,这个接口是一个类型约束,它包含 int 和 float64 类型。这意味着你只能传入 int 或 float64 类型的切片

  1. 使用泛型: 在调用泛型函数时,可以显式指定类型参数,也可以让编译器根据传入的参数进行类型推断
Print[int]([]int{1, 2, 3})
Print([]int{1, 2, 3}) // 类型推断
  1. 泛型数据结构: 可以创建泛型的结构体、接口、切片等数据结构
type Stack[T any] struct {
    elements []T
}
  1. 方法和泛型: 在泛型类型上可以定义方法
func (s *Stack[T]) Push(v T) {
    s.elements = append(s.elements, v)
}
  1. 嵌套的泛型类型: 泛型类型可以嵌入其他泛型类型
type Pair[T1, T2 any] struct {
    First  T1
    Second T2
}
  1. 泛型与接口: 泛型类型可以实现接口
func (p Pair[T1, T2]) String() string {
    return fmt.Sprintf("(%v, %v)", p.First, p.Second)
}

你可能感兴趣的:(golang)