GoLang之泛型

文章目录

  • GoLang之泛型
    • 1.实现非泛型函数
    • 2.实现泛型函数
    • 3.comparable接口类型

GoLang之泛型

注:本文已Go SDK v1.18进行讲解

1.实现非泛型函数

下面以 map 为例,先看非泛型如何处理,泛型又是如何处理。
假如有两个 map,分别是 map[string]int 和 map[string]float64,编写函数将 map 中的 value 值相加,返回结果。因为有两个类型,因此编写两个函数;
在 main 函数中初始化两个 map 并调用上面的函数

package main

import "fmt"

// SumInts adds together the values of m.
func SumInts(m map[string]int64) int64 {
	var s int64
	for _, v := range m {
		s += v
	}
	return s
}

// SumFloats adds together the values of m.
func SumFloats(m map[string]float64) float64 {
	var s float64
	for _, v := range m {
		s += v
	}
	return s
}
func main() {
	// Initialize a map for the integer values
	ints := map[string]int64{
		"first":  34,
		"second": 12,
	}

	// Initialize a map for the float values
	floats := map[string]float64{
		"first":  35.98,
		"second": 26.99,
	}

	fmt.Printf("Non-Generic Sums: %v and %v\n",
		SumInts(ints),
		SumFloats(floats))
}
//Non-Generic Sums: 46 and 62.97

虽然得到了想要的结果,但 SumInts 和 SumFloats 的逻辑差不多。如果将来有其他类型,我们必须增加额外的函数,代码逻辑也类似。
有了泛型,只需要一个函数就可以实现以上两个函数的功能,而且可以方便扩展为支持其他相关类型,比如 map[iint]float64 等

2.实现泛型函数

[K comparable, V Number]是类型参数;
(m map[K]V)是普通函数参数
map[K]V 是一个 map,它的 key 类型是 K,value 类型是 V

我们把原本来函数声明里的 int64和float64的并集改造成了一个新的“类型限制接口”Number,声明了int64和float64的并集,当我们需要限制类型参数为int64或float64时,就可以使用Number这个类型限制来代替int64 | float64的写法。
int | float64 表示只允许是 int 或 float64,其他类型编译会报错,这是“类型约束”

我们定义了一个新的泛型函数,函数逻辑和之前定义过的泛型函数SumIntsOrFloats完全一样,只不过对于类型参数V,我们使用了Number来作为类型限制。和之前一样,我们把类型参数用于函数形参和函数返回类型

比如SumNumbers(ints),这个泛型函数调用里,我们忽略了类型实参(方括号[]里面的类型名称),Go编译器根据函数实参进行自动类型推导。

type Number interface {
	int64 | float64
}

func SumNumbers[K comparable, V Number](m map[K]V) V {
	var s V
	for _, v := range m {
		s += v
	}
	return s
}
func main() {
	// Initialize a map for the integer values
	ints := map[string]int64{
		"first":  34,
		"second": 12,
	}

	// Initialize a map for the float values
	floats := map[string]float64{
		"first":  35.98,
		"second": 26.99,
	}

	fmt.Printf("Generic Sums with Constraint: %v and %v\n",
		SumNumbers(ints),
		SumNumbers(floats))
	//输出:Generic Sums with Constraint: 46 and 62.97
}

3.comparable接口类型

comparable表示所有可比较类型,也就是说,K 可以是任意可比较类型

type comparable interface{ comparable }

你可能感兴趣的:(GoLang,go)