求Golang的泛型编程实例
最近在学习Golang的泛型编程,但对具体实现还有些困惑。能否提供一个实际的泛型编程案例?比如如何用泛型实现一个通用的集合操作函数(如过滤、映射等)?最好能说明类型参数约束的使用场景,以及和之前用interface{}实现的方式相比有哪些改进。
3 回复
以下是一个Go语言中使用泛型的简单实例:
package main
import "fmt"
// 定义一个泛型函数,用于交换两个值
func Swap[T any](a *T, b *T) {
*a, *b = *b, *a
}
func main() {
var x int = 10
var y int = 20
Swap(&x, &y)
fmt.Println("Integers:", x, y)
var a string = "hello"
var b string = "world"
Swap(&a, &b)
fmt.Println("Strings:", a, b)
}
解释:
Swap
是一个泛型函数,[T any]
表示它可以处理任意类型。- 函数接收两个指向
T
类型的指针参数,并交换它们的值。 - 在
main
函数中,我们分别传入整数和字符串作为参数。
这个例子展示了Go 1.18引入的泛型特性,它允许编写更通用、可复用的代码。
更多关于求Golang的泛型编程实例的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
以下是一个Go语言泛型编程的简单实例,展示如何使用泛型来处理不同类型的整数和字符串:
package main
import "fmt"
// 定义一个泛型函数,用于交换两个值
func Swap[T any](a *T, b *T) {
*a, *b = *b, *a
}
func main() {
var x int = 10
var y int = 20
Swap(&x, &y)
fmt.Println("交换后:", x, y)
var s1 string = "hello"
var s2 string = "world"
Swap(&s1, &s2)
fmt.Println("交换后:", s1, s2)
}
这个例子中,Swap
是一个泛型函数,可以对任何类型的数据进行交换操作。通过 any
约束,允许传入任意类型的数据指针。在 main
函数中,分别对整数和字符串调用了该泛型函数,展示了泛型的灵活性。
Go语言泛型编程实例
Go语言在1.18版本正式引入了泛型(Generics)特性,下面通过几个实例展示如何使用Go泛型。
基础示例:泛型函数
package main
import "fmt"
// 泛型函数,可以处理任何可比较的类型
func Max[T comparable](a, b T) T {
if a > b {
return a
}
return b
}
func main() {
fmt.Println(Max(3, 5)) // 输出: 5
fmt.Println(Max(3.14, 2.71)) // 输出: 3.14
fmt.Println(Max("a", "b")) // 输出: b
}
泛型切片操作
package main
import "fmt"
// 泛型切片过滤函数
func Filter[T any](s []T, f func(T) bool) []T {
var result []T
for _, v := range s {
if f(v) {
result = append(result, v)
}
}
return result
}
func main() {
numbers := []int{1, 2, 3, 4, 5, 6}
even := Filter(numbers, func(n int) bool {
return n%2 == 0
})
fmt.Println(even) // 输出: [2 4 6]
}
泛型结构体
package main
import "fmt"
// 泛型栈结构
type Stack[T any] struct {
elements []T
}
func (s *Stack[T]) Push(element T) {
s.elements = append(s.elements, element)
}
func (s *Stack[T]) Pop() (T, bool) {
if len(s.elements) == 0 {
var zero T
return zero, false
}
element := s.elements[len(s.elements)-1]
s.elements = s.elements[:len(s.elements)-1]
return element, true
}
func main() {
stack := Stack[int]{}
stack.Push(1)
stack.Push(2)
stack.Push(3)
if elem, ok := stack.Pop(); ok {
fmt.Println(elem) // 输出: 3
}
}
类型约束
package main
import (
"fmt"
"golang.org/x/exp/constraints"
)
// 使用constraints包中的类型约束
func Sum[T constraints.Integer | constraints.Float](numbers []T) T {
var total T
for _, num := range numbers {
total += num
}
return total
}
func main() {
ints := []int{1, 2, 3}
floats := []float64{1.1, 2.2, 3.3}
fmt.Println(Sum(ints)) // 输出: 6
fmt.Println(Sum(floats)) // 输出: 6.6
}
注意事项:
- 类型参数用方括号
[]
表示 any
表示任何类型,相当于interface{}
comparable
表示可比较的类型- 可以使用
|
创建类型约束的联合