Go 语言泛型

以下是对 Go 语言泛型的汇总:

**一、泛型简介**

在 Go 1.18 及更高版本中引入了泛型,允许函数和类型在定义时使用类型参数,从而可以编写更通用、可重用的代码,避免了大量重复的代码逻辑。

**二、泛型函数**

1. 定义泛型函数:

package main

import "fmt"

func Map[T any](s []T, f func(T) T) []T {
    result := make([]T, len(s))
    for i, v := range s {
        result[i] = f(v)
    }
    return result
}


这个函数可以对任何类型的切片进行操作,传入一个切片和一个函数,函数用于对切片中的每个元素进行转换。

2. 调用泛型函数:

func main() {
    ints := []int{1, 2, 3}
    squaredInts := Map(ints, func(i int) int { return i * i })
    fmt.Println(squaredInts)

    strings := []string{"hello", "world"}
    upperStrings := Map(strings, func(s string) string { return s.toUpper() })
    fmt.Println(upperStrings)
}

**三、泛型类型**

1. 定义泛型类型:

package main

import "fmt"

type List[T any] struct {
    head *node[T]
}

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

func (l *List[T]) Add(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
    }
}

func (l *List[T]) Print() {
    current := l.head
    for current!= nil {
        fmt.Println(current.value)
        current = current.next
    }
}

这定义了一个通用的链表类型,可以存储任何类型的值。

2. 使用泛型类型:

func main() {
    intList := List[int]{}
    intList.Add(1)
    intList.Add(2)
    intList.Add(3)
    intList.Print()

    stringList := List[string]{}
    stringList.Add("hello")
    stringList.Add("world")
    stringList.Print()
}

**四、泛型约束**

可以对泛型类型参数进行约束,以限制可以使用的类型。

1. 使用接口作为约束:

package main

import "fmt"

type Number interface {
    int | int8 | int16 | int32 | int64 | float32 | float64
}

func Add[T Number](a, b T) T {
    return a + b
}
package main

import "fmt"

type Comparable interface {
    Compare(other interface{}) int
}

type MyStruct struct {
    value int
}

func (m MyStruct) Compare(other interface{}) int {
    if other.(MyStruct).value > m.value {
        return -1
    } else if other.(MyStruct).value < m.value {
        return 1
    } else {
        return 0
    }
}

func Max[T Comparable](a, b T) T {
    if a.Compare(b) < 0 {
        return b
    } else {
        return a
    }
}

实现了`Number`接口的类型作为参数。

2. 使用结构体作为约束:

这里定义了一个自定义的约束接口`Comparable`,只有实现了这个接口的类型才能用于`Max`函数。

**五、泛型的优势**

1. 代码复用:避免为不同类型编写重复的代码逻辑。
2. 类型安全:在编译时确保类型的正确性,减少运行时错误。
3. 可读性:使代码更清晰地表达其意图。

你可能感兴趣的:(go语言基础,golang)