← 泛型函数 | 类型约束 →

泛型类型 - 参数化数据结构

泛型类型允许定义参数化的数据结构,一套代码适用于多种类型。本节深入讲解泛型类型定义、方法、嵌套和实际应用。

📌 核心概念

📦

泛型类型

参数化结构

type T[K any]
🔧

泛型方法

类型参数方法

func (t T) M()
📚

数据结构

栈/队列/链表

通用实现
🔗

类型嵌套

泛型组合

嵌套参数

泛型类型定义

📝 定义泛型类型

package main

import "fmt"

// 泛型结构体
type Box[T any] struct {
    value T
}

// 泛型构造函数
func NewBox[T any](v T) *Box[T] {
    return &Box[T]{value: v}
}

// 泛型方法
func (b *Box[T]) Get() T {
    return b.value
}

func (b *Box[T]) Set(v T) {
    b.value = v
}

// 多类型参数结构体
type Pair[K any, V any] struct {
    Key   K
    Value V
}

func NewPair[K, V any](k K, v V) *Pair[K, V] {
    return &Pair[K, V]{Key: k, Value: v}
}

func main() {
    // 使用泛型 Box
    intBox := NewBox(42)
    fmt.Println(intBox.Get())
    
    strBox := NewBox("hello")
    fmt.Println(strBox.Get())
    
    // 使用泛型 Pair
    pair := NewPair("name", "Alice")
    fmt.Printf("%s: %s\n", pair.Key, pair.Value)
}

泛型数据结构

栈 (Stack)

📝 泛型栈实现

package main

import "fmt"

// 泛型栈
type Stack[T any] struct {
    items []T
}

func NewStack[T any]() *Stack[T] {
    return &Stack[T]{items: make([]T, 0)}
}

func (s *Stack[T]) Push(item T) {
    s.items = append(s.items, item)
}

func (s *Stack[T]) Pop() (T, bool) {
    var zero T
    if len(s.items) == 0 {
        return zero, false
    }
    item := s.items[len(s.items)-1]
    s.items = s.items[:len(s.items)-1]
    return item, true
}

func (s *Stack[T]) Peek() (T, bool) {
    var zero T
    if len(s.items) == 0 {
        return zero, false
    }
    return s.items[len(s.items)-1], true
}

func (s *Stack[T]) IsEmpty() bool {
    return len(s.items) == 0
}

func (s *Stack[T]) Size() int {
    return len(s.items)
}

func main() {
    stack := NewStack[int]()
    stack.Push(1)
    stack.Push(2)
    stack.Push(3)
    
    fmt.Println(stack.Pop()) // 3, true
    fmt.Println(stack.Peek())  // 2, true
    fmt.Println(stack.Size())  // 2
}

队列 (Queue)

📝 泛型队列实现

type Queue[T any] struct {
    items []T
}

func NewQueue[T any]() *Queue[T] {
    return &Queue[T]{items: make([]T, 0)}
}

func (q *Queue[T]) Enqueue(item T) {
    q.items = append(q.items, item)
}

func (q *Queue[T]) Dequeue() (T, bool) {
    var zero T
    if len(q.items) == 0 {
        return zero, false
    }
    item := q.items[0]
    q.items = q.items[1:]
    return item, true
}

func (q *Queue[T]) Front() (T, bool) {
    var zero T
    if len(q.items) == 0 {
        return zero, false
    }
    return q.items[0], true
}

链表 (Linked List)

📝 泛型链表实现

type Node[T any] struct {
    value T
    next  *Node[T]
}

type LinkedList[T any] struct {
    head *Node[T]
    size int
}

func NewLinkedList[T any]() *LinkedList[T] {
    return &LinkedList[T]{}
}

func (l *LinkedList[T]) Prepend(value T) {
    node := &Node[T]{value: value, next: l.head}
    l.head = node
    l.size++
}

func (l *LinkedList[T]) Append(value T) {
    newNode := &Node[T]{value: value}
    if l.head == nil {
        l.head = newNode
    } else {
        current := l.head
        for current.next != nil {
            current = current.next
        }
        current.next = newNode
    }
    l.size++
}

func (l *LinkedList[T]) Traverse(fn func(T)) {
    current := l.head
    for current != nil {
        fn(current.value)
        current = current.next
    }
}

类型嵌套和组合

📝 泛型嵌套使用

package main

import "fmt"

// 嵌套泛型
type Container[T any] struct {
    items []T
}

type NamedContainer[T any] struct {
    name      string
    container *Container[T]
}

func NewNamedContainer[T any](name string) *NamedContainer[T] {
    return &NamedContainer[T]{
        name:      name,
        container: NewContainer[T](),
    }
}

// 泛型接口组合
type Comparable interface {
    ~int | ~int64 | ~float64 | ~string
}

type SortedList[T Comparable] struct {
    items []T
}

func main() {
    // 嵌套泛型
    nc := NewNamedContainer[int]("numbers")
    
    // 泛型接口
    sl := &SortedList[int]{items: []int{3, 1, 2}}
    fmt.Println(sl.items)
}

最佳实践

✅ 泛型类型使用建议

  • 有意义的命名: T、K、V 等通用名称
  • 合理约束: 使用最宽松的约束
  • 零值处理: 注意空情况的返回值
  • 方法接收者: 指针接收者可修改内部状态

📖 延伸阅读