上卷 程序设计
中卷 标准库
- bufio 1.18
- bytes 1.18
- io 1.18
- container 1.18
- encoding 1.18
- crypto 1.18
- hash 1.18
- index 1.18
- sort 1.18
- context 1.18
- database 1.18
- connection
- query
- queryrow
- exec
- prepare
- transaction
- scan & null
- context
- tcp
- udp
- http
- server
- handler
- client
- h2、tls
- url
- rpc
- exec
- signal
- embed 1.18
- plugin 1.18
- reflect 1.18
- runtime 1.18
- KeepAlived
- ReadMemStats
- SetFinalizer
- Stack
- sync 1.18
- atomic
- mutex
- rwmutex
- waitgroup
- cond
- once
- map
- pool
- copycheck
- nocopy
- unsafe 1.18
- fmt 1.18
- log 1.18
- math 1.18
- time 1.18
- timer
下卷 运行时
源码剖析
附录
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
8. 泛型
泛型(generic)是一种代码复用技术,有时也称作模板(template)。允许在强类型语言代码中,使用实例化时才指定的 类型参数 (type parameter)。
- 函数和类型(含接口)支持类型参数,方法暂不支持。
- 支持推导,可省略类型实参(type argument)。
- 通常以单个大写字母命名类型参数。
- 类型参数必须有约束(constraints)。
package main import ( "cmp" ) func maxValue[T cmp.Ordered](x, y T) T { if x > y { return x } return y } func main() { println(maxValue[int](1, 2)) // 实例化,类型实参。 println(maxValue(1.1, 1.2)) // 类型推导,省略。 }
type Data[T any] struct { x T } func (d Data[T]) test() { fmt.Println(d) } // func (d Data[T]) test2[X any](x X) {} // ~~~~~~~ method must have no type parameters func main() { d := Data[int]{ x: 1 } d.test() }
可使用接口对类型参数进行约束,指示它能做什么。
如果是 any
,表示可传入任意类型对象。
其实
[T any]
还不如简写成[T]
。约束直接写在
[]
里,可能导致函数签名很难看,不如有个where
子句更优雅。希望后续版本能有所改变。
type N struct{} func (N) String() string { return "N" } func test[T fmt.Stringer](v T) { fmt.Println(v) } func main() { // test(1) // int does not implement fmt.Stringer (missing method String) test(N{}) }
类型集合
接口的两种定义:
- 普通接口 :方法集合(method sets),指示能做什么。
- 类型约束 :类型集合(type sets),指示谁来做。
相比普通接口 “被动、隐式” 实现,类型约束显式指定实现接口的类型集合。
type Integer interface { Signed | Unsigned } type Signed interface { ~int | ~int8 | ~int16 | ~int32 | ~int64 }
- 竖线:类型集,匹配其中任一类型即可。
- 波浪线:底层类型(underlying type)是该类型的所有类型。
func main() { // println(maxValue(struct{}{}, struct{}{})) // ~~~~~~~~ struct{} does not satisfy cmp.Ordered }
普通接口可用作约束,但类型约束却不能当普通接口使用。
func main() { // var x cmp.Ordered = 1 // ~~~~~~~~~~~~~~~~~~~ interface contains type constraints }
当然,类型约束除类型集合外,还可以有方法声明。
type A int type B string func (a A) Test() { println("A:", a) } func (b B) Test() { println("B:", b) } // ----------------------------------- type Tester interface { A | B Test() // 集合里的类型需要实现! } func test[T Tester](x T) { x.Test() // 约束调用! } // ----------------------------------- func main() { test[A](1) // test(A(1)) test[B]("abc") // test(B("abc")) // var c Tester = A(1) // ~~~~~~ interface contains type constraints // c.Test() }
类型约束
除含类型集合的接口类型外,也可直接写入参数列表。
[T any] // 任意类型。 [T int] // 只能是 int。 [T ~int] // 是 int 或底层类型是 int 的类型。 [T int | string] // 只能是 int 或 string。 [T io.Reader] // 任何实现 io.Reader 接口的类型。
func test[T int | float32](x T) { fmt.Printf("%T, %v\n", x, x) } func main() { test(1) test[float32](1.1) // test("abc") // ~~~ string does not satisfy int|float32 }
func makeSlice[T int | float64](x T) []T { s := make([]T, 10) for i := 0; i < cap(s); i++ { s[i] = x } return s }
func test[T int | float64, E ~[]T](x E) { for v := range x { fmt.Println(v) } } func main() { test([]int{1, 2, 3}) test([]float64{1.1, 1.2, 1.3}) }
如类型约束不是接口,则无法调用其成员。
type Num int func (n Num) print() { println(n) } func test[T Num](n T) { // n.print() // ~~~~~~~ n.print undefined (type T has no field or method print) } func main() { test(1) }
类型转换
不支持 switch
类型推断(type assert),须转换为普通接口。
func test[T any](x T) { // switch x.(type) {} // ~~~~ cannot use type switch on type parameter value x // 转换为普通接口 ---------- switch any(x).(type) { case int: println("int", x) } }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论