最近go 1.18发布,有好多新特性,这里来体验下
- 支持泛型 Generics
- 模糊测试 Fuzzing
- 工作区 Workspaces
- 性能提升20%
更多有关1.18版本的更新,可以参考 release notes
这里先来体验一下泛型吧
背景知识
-
有关 golang 泛型的体验,可以参考 generics tutorial
-
有关为什么Golang要引入泛型,参考:Why Generics? - The Go Programming Language
-
环境:可以使用本地环境(直接在goland下载1.18+的版本),也可以使用线上环境 Go Playground - The Go Programming Language
-
~T:~是Go 1.18新增的符号,~T表示底层类型是T的所有类型。例如~int表示底层类型为int的类型,type MyInt int,则MyInt符合~int的定义 -
comparable: 新增的可比较类型
泛型
包含底层类型的泛型
如下所示,定义了泛型的Int,Uint,Float,Number等类型,进行Sum,Max等操作
package main
import "fmt"
func main() {
n1 := MyInt(1)
n2 := MyInt(2)
fmt.Printf("sum of int: %d \n", Sum(n1, n2))
fmt.Printf("sum of float: %.3f \n", Sum(1.1, 2.2))
fmt.Printf("max of string: %s \n", Max("a1", "b1"))
}
type MyInt int
func Sum[N Number](a N, b N) N {
return a + b
}
// Int 所有底层类型为为int/int8...等,均符合Int泛型定义
type Int interface {
~int | ~int8 | ~int16 | ~int32 | ~int64
}
type Uint interface {
uint | uint8 | uint16 | uint32 | uint64
}
type Float interface {
float32 | float64
}
// Number 包含了所有数字的定义
type Number interface {
Int | Uint | Float
}
type ordered interface {
Int | Uint | uintptr | Float | string
}
func Max[T ordered](a, b T) T {
if a < b {
return b
}
return a
}
这里对常用的泛型进行了一个归纳,在后续的泛型编程中,可以直接使用
// Signed 有符号整数
type Signed interface {
~int | ~int8 | ~int16 | ~int32 | ~int64
}
// Unsigned 无符号整数
type Unsigned interface {
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
}
// Integer 所有整数
type Integer interface {
Signed | Unsigned
}
// Float 浮点数
type Float interface {
~float32 | ~float64
}
// Complex 复数
type Complex interface {
~complex64 | ~complex128
}
// Ordered 支持比较的类型
type Ordered interface {
Integer | Float | ~string
}
// Slice 任意类型的 slice
type Slice[Elem any] interface {
~[]Elem
}
// Map 任意类型的 map
type Map[Key comparable, Val any] interface {
~map[Key]Val
}
// Chan 任意类型的 channel
type Chan[Elem any] interface {
~chan Elem
}
comparable和any
有关compareble的定义,可以参考:Type Parameters Proposal (googlesource.com)
源码注释中是这么写的:
// any is an alias for interface{} and is equivalent to interface{} in all ways.
type any = interface{}
// comparable is an interface that is implemented by all comparable types
// (booleans, numbers, strings, pointers, channels, arrays of comparable types,
// structs whose fields are all comparable types).
// The comparable interface may only be used as a type parameter constraint,
// not as the type of a variable.
type comparable interface{ comparable }
any等同于interface{}comparable包含所有的可比较类型,需要注意的是:这是一种约束,不是一种变量。被约束为comparable的类型,可以进行==和!=的比较。
func main() {
fmt.Printf("a == b? %t \n", Equal("a", "b"))
fmt.Printf("1 == 1? %t \n", Equal(1, 1))
}
func Equal[T comparable](a, b T) bool {
return a == b
}
输出
a == b? false
1 == 1? true