在最新的go1.18版中增加了期盼已久的泛型支持
泛型是程序设计语言的一种风格或范式。泛型允许程序员在强类型程序设计语言中编写代码时使用一些以后才指定的类型,在实例化时作为参数指明这些类型。
如果没有泛型,对于golang语言这种强类型语言,针对不同类型的函数解决方式:
以int64和int类型为例:
func CompareInt64(a, b int64) bool {
if a >= b {
return true
}
return false
}
func CompareInt(a, b int) bool {
if a >= b {
return true
}
return false
}
func Compare(a, b interface{}) bool {
switch a.(type) {
case int64:
a1 := a.(int64)
b1 := b.(int64)
if a1 >= b1 {
return true
}
return false
case int:
a1 := a.(int)
b1 := b.(int)
if a1 >= b1 {
return true
}
return false
default:
return false
}
}
使用泛型 golang支持泛型函数和泛型类型
// 泛型函数
func F[T any](p T) (args T){ ... }
[T any]为类型约束,any 表示任意类型,(args T)为参数。
使用泛型实现上例
func Compare[T int64|int](a, b T) bool {
if a >= b {
return true
}
return false
}
参数多的话也可这样
type TT interface {
int | int64
}
func Compare[T TT|int](a, b T) bool {
if a >= b {
return true
}
return false
}
有了泛型后:
package main
import (
"fmt"
)
// 泛型切片
type Name[T any] []T
type TestSilce [T int | float64] []T
func ListElem[T int | float64 | string](params []T) {
for _, elem := range params {
fmt.Printf("类型=%T,val=%+v\n", elem, elem)
}
return
}
func main() {
v := Name[string]{"a", "b"}
fmt.Printf("类型=%T,val=%+v\n", v, v)
ListElem(v)
l := TestSilce[int]{1, 2, 3}
fmt.Printf("类型=%T,val=%+v\n", l, l)
ListElem(l)
}
预声明标识符 comparable是一个接口,表示可以使用==or进行比较的所有类型的集合!=。它只能用作(或嵌入)类型约束。
package main
import "fmt"
type Number interface {
int64 | float64
}
type M[K string ,V any] map[K]V
func main() {
// Initialize a map for the integer values
ints := M[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: %v and %v\n",
SumIntsOrFloats[string, int64](ints),
SumIntsOrFloats[string, float64](floats))
fmt.Printf("Generic Sums, type parameters inferred: %v and %v\n",
SumIntsOrFloats(ints),
SumIntsOrFloats(floats))
fmt.Printf("Generic Sums with Constraint: %v and %v\n",
SumNumbers(ints),
SumNumbers(floats))
}
// SumIntsOrFloats sums the values of map m. It supports both floats and integers
// as map values.
func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}
// SumNumbers sums the values of map m. Its supports both integers
// and floats as map values.
func SumNumbers[K comparable, V Number](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}
package main
import "fmt"
type Number interface {
int64 | float64
}
type Stack[V Number] struct {
size int64
value []V
}
func (s *Stack[V]) Push(v V) {
s.value = append(s.value, v)
s.size++
}
func main() {
s := &Stack[int64]{}
s.Push(1)
fmt.Printf(" %T and %v\n",s,s)
}
package main
import "fmt"
type Ch[T any] chan T
func main() {
ch := make(Ch[int], 1)
ch <- 10
res := <-ch
fmt.Printf("类型=%T,val=%+v", res, res)
}
函数和 类型声明 的语法 现在接受 类型参数。 参数化函数和类型可以通过在它们后面加上方括号中的类型参数列表来实例化。 新标记~已添加到 运算符和标点符号集中。 预声明标识符 any是空接口的别名。它可以代替 interface{}. 接口类型 的语法 现在允许嵌入任意类型(不仅仅是接口的类型名称)以及联合和~T类型元素。此类接口只能用作类型约束。一个接口现在定义了一组类型和一组方法。 预声明标识符 comparable是一个接口,表示可以使用==or进行比较的所有类型的集合!=。它只能用作(或嵌入)类型约束。 加入泛型后对编译性能有影响,编译速度慢了15%。
https://go.dev/doc/tutorial/g... https://blog.csdn.net/Jcduhdt...