golang编程核心-泛型

内容分享12小时前发布
0 0 0

Go 1.18的发布标志着Go语言进入了一个新的时代——泛型时代。泛型的引入解决了Go语言长期以来在类型安全和代码复用方面的痛点,让Go语言在保持简洁性的同时,获得了更强的表达力。

// 泛型基础示例
func genericBasics() {
    // 泛型函数
    fmt.Println(max(10, 20))           // 输出: 20
    fmt.Println(max(3.14, 2.71))       // 输出: 3.14
    fmt.Println(max("apple", "banana")) // 输出: banana
    
    // 泛型类型
    var intStack Stack[int]
    intStack.Push(1)
    intStack.Push(2)
    fmt.Println(intStack.Pop()) // 输出: 2
    
    var stringStack Stack[string]
    stringStack.Push("hello")
    stringStack.Push("world")
    fmt.Println(stringStack.Pop()) // 输出: world
}

// 泛型函数
func max[T comparable](a, b T) T {
    if a > b {
        return a
    }
    return b
}

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

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

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

类型参数语法

// 类型参数语法
func typeParameterSyntax() {
    // 1. 函数类型参数
    func identity[T any](x T) T {
        return x
    }
    
    // 2. 类型类型参数
    type Container[T any] struct {
        value T
    }
    
    // 3. 方法类型参数
    func (c *Container[T]) Set(value T) {
        c.value = value
    }
    
    func (c *Container[T]) Get() T {
        return c.value
    }
    
    // 使用示例
    container := &Container[int]{value: 42}
    fmt.Printf("容器值: %d
", container.Get())
    
    container.Set(100)
    fmt.Printf("新值: %d
", container.Get())
}

类型约束

基本约束

// 基本类型约束
func basicConstraints() {
    // 1. comparable约束 - 可比较类型
    func findIndex[T comparable](slice []T, target T) int {
        for i, v := range slice {
            if v == target {
                return i
            }
        }
        return -1
    }
    
    // 2. any约束 - 任意类型
    func printValue[T any](value T) {
        fmt.Printf("值: %v
", value)
    }
    
    // 3. 自定义约束
    type Numeric interface {
        ~int | ~int8 | ~int16 | ~int32 | ~int64 |
        ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 |
        ~float32 | ~float64
    }
    
    func add[T Numeric](a, b T) T {
        return a + b
    }
    
    // 使用示例
    numbers := []int{1, 2, 3, 4, 5}
    index := findIndex(numbers, 3)
    fmt.Printf("索引: %d
", index)
    
    printValue("Hello, World!")
    printValue(42)
    printValue(3.14)
    
    result := add(10, 20)
    fmt.Printf("加法结果: %d
", result)
}

复杂约束

// 复杂约束
func complexConstraints() {
    // 1. 方法约束
    type Stringer interface {
        String() string
    }
    
    func printString[T Stringer](value T) {
        fmt.Println(value.String())
    }
    
    // 2. 组合约束
    type ComparableStringer interface {
        comparable
        String() string
    }
    
    func compareAndPrint[T ComparableStringer](a, b T) {
        if a == b {
            fmt.Printf("相等: %s
", a.String())
        } else {
            fmt.Printf("不相等: %s != %s
", a.String(), b.String())
        }
    }
    
    // 3. 类型集约束
    type Ordered interface {
        ~int | ~int8 | ~int16 | ~int32 | ~int64 |
        ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 |
        ~float32 | ~float64 | ~string
    }
    
    func sortSlice[T Ordered](slice []T) []T {
        result := make([]T, len(slice))
        copy(result, slice)
        
        // 简单的冒泡排序
        for i := 0; i < len(result)-1; i++ {
            for j := 0; j < len(result)-i-1; j++ {
                if result[j] > result[j+1] {
                    result[j], result[j+1] = result[j+1], result[j]
                }
            }
        }
        
        return result
    }
    
    // 使用示例
    numbers := []int{3, 1, 4, 1, 5, 9, 2, 6}
    sorted := sortSlice(numbers)
    fmt.Printf("排序结果: %v
", sorted)
    
    strings := []string{"banana", "apple", "cherry"}
    sortedStrings := sortSlice(strings)
    fmt.Printf("字符串排序: %v
", sortedStrings)
}

泛型数据结构

泛型容器

// 泛型容器
func genericContainers() {
    // 1. 泛型切片
    type GenericSlice[T any] []T
    
    func (s GenericSlice[T]) Filter(predicate func(T) bool) GenericSlice[T] {
        var result GenericSlice[T]
        for _, item := range s {
            if predicate(item) {
                result = append(result, item)
            }
        }
        return result
    }
    
    func (s GenericSlice[T]) Map[U any](mapper func(T) U) GenericSlice[U] {
        result := make(GenericSlice[U], len(s))
        for i, item := range s {
            result[i] = mapper(item)
        }
        return result
    }
    
    // 2. 泛型映射
    type GenericMap[K comparable, V any] map[K]V
    
    func (m GenericMap[K, V]) Get(key K) (V, bool) {
        value, ok := m[key]
        return value, ok
    }
    
    func (m GenericMap[K, V]) Set(key K, value V) {
        m[key] = value
    }
    
    func (m GenericMap[K, V]) Keys() []K {
        keys := make([]K, 0, len(m))
        for k := range m {
            keys = append(keys, k)
        }
        return keys
    }
    
    // 使用示例
    numbers := GenericSlice[int]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    evens := numbers.Filter(func(n int) bool {
        return n%2 == 0
    })
    fmt.Printf("偶数: %v
", evens)
    
    squares := numbers.Map(func(n int) int {
        return n * n
    })
    fmt.Printf("平方: %v
", squares)
    
    userMap := make(GenericMap[string, int])
    userMap.Set("Alice", 25)
    userMap.Set("Bob", 30)
    
    if age, ok := userMap.Get("Alice"); ok {
        fmt.Printf("Alice的年龄: %d
", age)
    }
}

泛型队列和栈

// 泛型队列和栈
func genericQueueAndStack() {
    // 1. 泛型队列
    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) {
        if len(q.items) == 0 {
            var zero T
            return zero, false
        }
        
        item := q.items[0]
        q.items = q.items[1:]
        return item, true
    }
    
    func (q *Queue[T]) Size() int {
        return len(q.items)
    }
    
    // 2. 泛型栈
    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) {
        if len(s.items) == 0 {
            var zero T
            return zero, false
        }
        
        index := len(s.items) - 1
        item := s.items[index]
        s.items = s.items[:index]
        return item, true
    }
    
    func (s *Stack[T]) Peek() (T, bool) {
        if len(s.items) == 0 {
            var zero T
            return zero, false
        }
        
        return s.items[len(s.items)-1], true
    }
    
    // 使用示例
    queue := NewQueue[string]()
    queue.Enqueue("first")
    queue.Enqueue("second")
    queue.Enqueue("third")
    
    for queue.Size() > 0 {
        if item, ok := queue.Dequeue(); ok {
            fmt.Printf("出队: %s
", item)
        }
    }
    
    stack := NewStack[int]()
    stack.Push(1)
    stack.Push(2)
    stack.Push(3)
    
    for {
        if item, ok := stack.Pop(); ok {
            fmt.Printf("出栈: %d
", item)
        } else {
            break
        }
    }
}

泛型算法

泛型排序

// 泛型排序
func genericSorting() {
    // 1. 泛型快速排序
    func quickSort[T Ordered](slice []T) {
        if len(slice) < 2 {
            return
        }
        
        pivot := slice[len(slice)/2]
        left, right := 0, len(slice)-1
        
        for left <= right {
            for slice[left] < pivot {
                left++
            }
            for slice[right] > pivot {
                right--
            }
            if left <= right {
                slice[left], slice[right] = slice[right], slice[left]
                left++
                right--
            }
        }
        
        quickSort(slice[:right+1])
        quickSort(slice[left:])
    }
    
    // 2. 泛型二分查找
    func binarySearch[T Ordered](slice []T, target T) int {
        left, right := 0, len(slice)-1
        
        for left <= right {
            mid := (left + right) / 2
            if slice[mid] == target {
                return mid
            } else if slice[mid] < target {
                left = mid + 1
            } else {
                right = mid - 1
            }
        }
        
        return -1
    }
    
    // 3. 泛型归并排序
    func mergeSort[T Ordered](slice []T) []T {
        if len(slice) < 2 {
            return slice
        }
        
        mid := len(slice) / 2
        left := mergeSort(slice[:mid])
        right := mergeSort(slice[mid:])
        
        return merge(left, right)
    }
    
    func merge[T Ordered](left, right []T) []T {
        result := make([]T, 0, len(left)+len(right))
        i, j := 0, 0
        
        for i < len(left) && j < len(right) {
            if left[i] <= right[j] {
                result = append(result, left[i])
                i++
            } else {
                result = append(result, right[j])
                j++
            }
        }
        
        result = append(result, left[i:]...)
        result = append(result, right[j:]...)
        
        return result
    }
    
    // 使用示例
    numbers := []int{64, 34, 25, 12, 22, 11, 90}
    fmt.Printf("原始数组: %v
", numbers)
    
    quickSort(numbers)
    fmt.Printf("快速排序: %v
", numbers)
    
    index := binarySearch(numbers, 25)
    fmt.Printf("二分查找25的索引: %d
", index)
    
    unsorted := []int{64, 34, 25, 12, 22, 11, 90}
    sorted := mergeSort(unsorted)
    fmt.Printf("归并排序: %v
", sorted)
}

泛型搜索

// 泛型搜索
func genericSearch() {
    // 1. 泛型线性搜索
    func linearSearch[T comparable](slice []T, target T) int {
        for i, v := range slice {
            if v == target {
                return i
            }
        }
        return -1
    }
    
    // 2. 泛型条件搜索
    func findFirst[T any](slice []T, predicate func(T) bool) (T, bool) {
        for _, v := range slice {
            if predicate(v) {
                return v, true
            }
        }
        var zero T
        return zero, false
    }
    
    // 3. 泛型过滤
    func filter[T any](slice []T, predicate func(T) bool) []T {
        var result []T
        for _, v := range slice {
            if predicate(v) {
                result = append(result, v)
            }
        }
        return result
    }
    
    // 4. 泛型映射
    func mapSlice[T, U any](slice []T, mapper func(T) U) []U {
        result := make([]U, len(slice))
        for i, v := range slice {
            result[i] = mapper(v)
        }
        return result
    }
    
    // 使用示例
    numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    
    index := linearSearch(numbers, 5)
    fmt.Printf("线性搜索5的索引: %d
", index)
    
    if value, ok := findFirst(numbers, func(n int) bool {
        return n > 5
    }); ok {
        fmt.Printf("第一个大于5的数: %d
", value)
    }
    
    evens := filter(numbers, func(n int) bool {
        return n%2 == 0
    })
    fmt.Printf("偶数: %v
", evens)
    
    squares := mapSlice(numbers, func(n int) int {
        return n * n
    })
    fmt.Printf("平方: %v
", squares)
}

泛型接口

泛型接口定义

// 泛型接口
func genericInterfaces() {
    // 1. 泛型接口
    type Container[T any] interface {
        Add(item T)
        Remove(item T) bool
        Contains(item T) bool
        Size() int
    }
    
    // 2. 泛型比较接口
    type Comparable[T any] interface {
        Compare(other T) int
    }
    
    // 3. 泛型迭代器接口
    type Iterator[T any] interface {
        Next() bool
        Value() T
    }
    
    // 实现泛型接口
    type GenericSet[T comparable] struct {
        items map[T]bool
    }
    
    func NewGenericSet[T comparable]() *GenericSet[T] {
        return &GenericSet[T]{
            items: make(map[T]bool),
        }
    }
    
    func (s *GenericSet[T]) Add(item T) {
        s.items[item] = true
    }
    
    func (s *GenericSet[T]) Remove(item T) bool {
        if s.items[item] {
            delete(s.items, item)
            return true
        }
        return false
    }
    
    func (s *GenericSet[T]) Contains(item T) bool {
        return s.items[item]
    }
    
    func (s *GenericSet[T]) Size() int {
        return len(s.items)
    }
    
    // 使用示例
    set := NewGenericSet[int]()
    set.Add(1)
    set.Add(2)
    set.Add(3)
    
    fmt.Printf("集合大小: %d
", set.Size())
    fmt.Printf("包含2: %t
", set.Contains(2))
    
    set.Remove(2)
    fmt.Printf("移除2后大小: %d
", set.Size())
    fmt.Printf("包含2: %t
", set.Contains(2))
}

泛型方法

// 泛型方法
func genericMethods() {
    // 1. 泛型方法
    type Processor[T any] struct {
        data T
    }
    
    func (p *Processor[T]) Process[U any](mapper func(T) U) U {
        return mapper(p.data)
    }
    
    func (p *Processor[T]) Transform[U any](transformer func(T) U) *Processor[U] {
        return &Processor[U]{data: transformer(p.data)}
    }
    
    // 2. 泛型链式调用
    type Chain[T any] struct {
        value T
    }
    
    func NewChain[T any](value T) *Chain[T] {
        return &Chain[T]{value: value}
    }
    
    func (c *Chain[T]) Map[U any](mapper func(T) U) *Chain[U] {
        return &Chain[U]{value: mapper(c.value)}
    }
    
    func (c *Chain[T]) Filter(predicate func(T) bool) *Chain[T] {
        if predicate(c.value) {
            return c
        }
        return nil
    }
    
    func (c *Chain[T]) Value() T {
        return c.value
    }
    
    // 使用示例
    processor := &Processor[int]{data: 42}
    result := processor.Process(func(x int) string {
        return fmt.Sprintf("数字: %d", x)
    })
    fmt.Printf("处理结果: %s
", result)
    
    transformed := processor.Transform(func(x int) float64 {
        return float64(x) * 2.5
    })
    fmt.Printf("转换结果: %.2f
", transformed.data)
    
    chain := NewChain(10)
    result2 := chain.Map(func(x int) int {
        return x * 2
    }).Map(func(x int) string {
        return fmt.Sprintf("结果: %d", x)
    }).Value()
    fmt.Printf("链式调用结果: %s
", result2)
}

类型推断

自动类型推断

// 类型推断
func typeInference() {
    // 1. 自动类型推断
    func identity[T any](x T) T {
        return x
    }
    
    // 编译器自动推断类型
    result1 := identity(42)        // T 被推断为 int
    result2 := identity("hello")   // T 被推断为 string
    result3 := identity(3.14)      // T 被推断为 float64
    
    fmt.Printf("结果1: %d
", result1)
    fmt.Printf("结果2: %s
", result2)
    fmt.Printf("结果3: %.2f
", result3)
    
    // 2. 显式类型指定
    result4 := identity[int](42)           // 显式指定 T 为 int
    result5 := identity[string]("world")   // 显式指定 T 为 string
    
    fmt.Printf("显式类型结果1: %d
", result4)
    fmt.Printf("显式类型结果2: %s
", result5)
    
    // 3. 复杂类型推断
    func process[T any](slice []T, processor func(T) T) []T {
        result := make([]T, len(slice))
        for i, v := range slice {
            result[i] = processor(v)
        }
        return result
    }
    
    numbers := []int{1, 2, 3, 4, 5}
    doubled := process(numbers, func(x int) int {
        return x * 2
    })
    fmt.Printf("翻倍结果: %v
", doubled)
    
    strings := []string{"hello", "world"}
    uppercased := process(strings, func(s string) string {
        return strings.ToUpper(s)
    })
    fmt.Printf("大写结果: %v
", uppercased)
}

实战应用

泛型缓存

// 泛型缓存
func genericCache() {
    type Cache[K comparable, V any] struct {
        mu    sync.RWMutex
        data  map[K]V
        maxSize int
    }
    
    func NewCache[K comparable, V any](maxSize int) *Cache[K, V] {
        return &Cache[K, V]{
            data:    make(map[K]V),
            maxSize: maxSize,
        }
    }
    
    func (c *Cache[K, V]) Get(key K) (V, bool) {
        c.mu.RLock()
        defer c.mu.RUnlock()
        value, ok := c.data[key]
        return value, ok
    }
    
    func (c *Cache[K, V]) Set(key K, value V) {
        c.mu.Lock()
        defer c.mu.Unlock()
        
        if len(c.data) >= c.maxSize {
            // 简单的LRU实现:删除第一个元素
            for k := range c.data {
                delete(c.data, k)
                break
            }
        }
        
        c.data[key] = value
    }
    
    func (c *Cache[K, V]) Delete(key K) {
        c.mu.Lock()
        defer c.mu.Unlock()
        delete(c.data, key)
    }
    
    func (c *Cache[K, V]) Size() int {
        c.mu.RLock()
        defer c.mu.RUnlock()
        return len(c.data)
    }
    
    // 使用示例
    cache := NewCache[string, int](3)
    cache.Set("one", 1)
    cache.Set("two", 2)
    cache.Set("three", 3)
    
    if value, ok := cache.Get("one"); ok {
        fmt.Printf("缓存命中: one = %d
", value)
    }
    
    cache.Set("four", 4) // 会触发LRU
    
    fmt.Printf("缓存大小: %d
", cache.Size())
}

泛型API响应

// 泛型API响应
func genericAPIResponse() {
    type APIResponse[T any] struct {
        Success bool   `json:"success"`
        Message string `json:"message"`
        Data    T      `json:"data,omitempty"`
    }
    
    type User struct {
        ID    int    `json:"id"`
        Name  string `json:"name"`
        Email string `json:"email"`
    }
    
    type Product struct {
        ID    int     `json:"id"`
        Name  string  `json:"name"`
        Price float64 `json:"price"`
    }
    
    // 创建用户响应
    userResp := APIResponse[User]{
        Success: true,
        Message: "获取用户成功",
        Data: User{
            ID:    1,
            Name:  "Alice",
            Email: "alice@example.com",
        },
    }
    
    // 创建产品响应
    productResp := APIResponse[Product]{
        Success: true,
        Message: "获取产品成功",
        Data: Product{
            ID:    1,
            Name:  "Laptop",
            Price: 999.99,
        },
    }
    
    // 创建列表响应
    usersResp := APIResponse[[]User]{
        Success: true,
        Message: "获取用户列表成功",
        Data: []User{
            {ID: 1, Name: "Alice", Email: "alice@example.com"},
            {ID: 2, Name: "Bob", Email: "bob@example.com"},
        },
    }
    
    fmt.Printf("用户响应: %+v
", userResp)
    fmt.Printf("产品响应: %+v
", productResp)
    fmt.Printf("用户列表响应: %+v
", usersResp)
}

性能思考

泛型性能

// 泛型性能
func genericPerformance() {
    // 1. 泛型函数的性能
    func genericAdd[T Numeric](a, b T) T {
        return a + b
    }
    
    // 2. 非泛型函数的性能
    func intAdd(a, b int) int {
        return a + b
    }
    
    // 性能测试
    func benchmarkGenericAdd(b *testing.B) {
        for i := 0; i < b.N; i++ {
            _ = genericAdd(10, 20)
        }
    }
    
    func benchmarkIntAdd(b *testing.B) {
        for i := 0; i < b.N; i++ {
            _ = intAdd(10, 20)
        }
    }
    
    // 3. 泛型类型的性能
    type GenericContainer[T any] struct {
        value T
    }
    
    type IntContainer struct {
        value int
    }
    
    // 泛型容器的性能一般与非泛型容器相当
    // 由于Go编译器会进行单态化
}

最佳实践

泛型最佳实践

// 泛型最佳实践
func genericBestPractices() {
    // 1. 使用有意义的约束
    type Numeric interface {
        ~int | ~int8 | ~int16 | ~int32 | ~int64 |
        ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 |
        ~float32 | ~float64
    }
    
    // 2. 避免过度泛型化
    // 不要为了泛型而泛型,只在真正需要时使用
    
    // 3. 使用类型别名提高可读性
    type UserID = int
    type ProductID = int
    
    type User struct {
        ID   UserID
        Name string
    }
    
    type Product struct {
        ID    ProductID
        Name  string
        Price float64
    }
    
    // 4. 合理使用类型推断
    func process[T any](data T) T {
        return data
    }
    
    // 让编译器推断类型
    result := process(42)
    fmt.Printf("推断结果: %d
", result)
    
    // 5. 使用泛型接口提高灵活性
    type Repository[T any] interface {
        Save(entity T) error
        FindByID(id int) (T, error)
        Delete(id int) error
    }
    
    // 6. 思考向后兼容性
    // 在现有代码中引入泛型时要小心
}

写在最后

泛型是Go语言发展史上的重大里程碑,它让Go语言在保持简洁性的同时,获得了更强的表达力。从简单的类型参数到复杂的约束系统,泛型为Go语言带来了革命性的变化。

作为Go开发者,掌握泛型的使用不仅能够提高代码的类型安全性和可复用性,还能让我们更好地理解Go语言的设计哲学。通过合理使用泛型,我们可以构建出更加优雅和类型安全的Go程序。

记住,泛型不仅仅是工具,更是Go语言表达力的体现。通过泛型,我们可以实现更加灵活和强劲的类型系统,构建出更加优雅和可维护的Go程序。

© 版权声明

相关文章

暂无评论

none
暂无评论...