|
| 1 | +# go2generics  |
| 2 | + |
| 3 | +中文 | [English](./README.md) |
| 4 | + |
| 5 | +Go 语言泛型的代码示例(基于类型参数和类型集) |
| 6 | + |
| 7 | +## 支持泛型的 Go 编译器 |
| 8 | + |
| 9 | +正在开发阶段的 Go 编译器(称之为 [gotip](https://pkg.go.dev/golang.org/dl/gotip))支持类型参数和类型集编写的泛型代码。可以通过下面的命令进行安装: |
| 10 | + |
| 11 | +```sh |
| 12 | +$ go get golang.org/dl/gotip |
| 13 | +$ gotip download |
| 14 | +$ gotip version |
| 15 | +go version devel go1.18-6e50991 Sat Aug 21 18:23:58 2021 +0000 darwin/arm64 |
| 16 | +``` |
| 17 | + |
| 18 | +## 标准库 |
| 19 | + |
| 20 | +下面这些包将出现在 Go 1.18 的发行版中: |
| 21 | + |
| 22 | +### `constraints` 包 |
| 23 | + |
| 24 | +该包基于这些提案: |
| 25 | + |
| 26 | +- [golang/go#45458](https://golang.org/issue/45458) proposal: constraints: new package to define standard type parameter constraints |
| 27 | +- [golang/go#47319](https://golang.org/issue/47319) proposal: constraints: new package to define standard type parameter constraints (discussion) |
| 28 | + |
| 29 | +可以在[这里](./std/constraints)找到一个可能的实现。 |
| 30 | + |
| 31 | +```go |
| 32 | +package constraints |
| 33 | + |
| 34 | +type Signed interface |
| 35 | +type Unsigned interface |
| 36 | +type Integer interface |
| 37 | +type Float interface |
| 38 | +type Complex interface |
| 39 | +type Ordered interface |
| 40 | +type Slice[Elem any] interface |
| 41 | +type Map[Key comparable, Val any] interface |
| 42 | +type Chan[Elem any] interface |
| 43 | +``` |
| 44 | + |
| 45 | +### `slices` 包 |
| 46 | + |
| 47 | +该包基于这些提案: |
| 48 | + |
| 49 | +- [golang/go#45955](https://golang.org/issue/45955) proposal: slices: new package to provide generic slice functions |
| 50 | +- [golang/go#47203](https://golang.org/issue/47203) proposal: slices: new package to provide generic slice functions (discussion) |
| 51 | + |
| 52 | +可以在[这里](./std/slices)找到一个可能的实现。 |
| 53 | + |
| 54 | +```go |
| 55 | +package slices |
| 56 | + |
| 57 | +import "constraints" |
| 58 | + |
| 59 | +func Equal[T comparable](s1, s2 []T) bool |
| 60 | +func EqualFunc[T1, T2 any](s1 []T1, s2 []T2, eq func(T1, T2) bool) bool |
| 61 | +func Compare[T constraints.Ordered](s1, s2 []T) int |
| 62 | +func CompareFunc[T any](s1, s2 []T, cmp func(T, T) int) int |
| 63 | +func Index[T comparable](s []T, v T) int |
| 64 | +func IndexFunc[T any](s []T, f func(T) bool) int |
| 65 | +func Contains[T comparable](s []T, v T) bool |
| 66 | +func Insert[S constraints.Slice[T], T any](s S, i int, v ...T) S |
| 67 | +func Delete[S constraints.Slice[T], T any](s S, i, j int) S |
| 68 | +func Clone[S constraints.Slice[T], T any](s S) S |
| 69 | +func Compact[S constraints.Slice[T], T comparable](s S) S |
| 70 | +func CompactFunc[S constraints.Slice[T], T any](s S, cmp func(T, T) bool) S |
| 71 | +func Grow[S constraints.Slice[T], T any](s S, n int) S |
| 72 | +func Clip[S constraints.Slice[T], T any](s S) S |
| 73 | +``` |
| 74 | + |
| 75 | +### `maps` 包 |
| 76 | + |
| 77 | +该包基于这些提案: |
| 78 | + |
| 79 | +- [golang/go#47649](https://golang.org/issue/47649) proposal: maps: new package to provide generic map functions |
| 80 | +- [golang/go#47330](https://golang.org/issue/47330) proposal: maps: new package to provide generic map functions (discussion) |
| 81 | + |
| 82 | +可以在[这里](./std/maps)找到一个可能的实现。 |
| 83 | + |
| 84 | +```go |
| 85 | +package maps |
| 86 | + |
| 87 | +func Keys[K comparable, V any](m map[K]V) []K |
| 88 | +func Values[K comparable, V any](m map[K]V) []V |
| 89 | +func Equal[K, V comparable](m1, m2 map[K]V) bool |
| 90 | +func EqualFunc[K comparable, V1, V2 any](m1 map[K]V1, m2 map[K]V2, cmp func(V1, V2) bool) bool |
| 91 | +func Clear[K comparable, V any](m map[K]V) |
| 92 | +func Clone[K comparable, V any](m map[K]V) map[K]V |
| 93 | +func Add[K comparable, V any](dst, src map[K]V) |
| 94 | +func Filter[K comparable, V any](m map[K]V, keep func(K, V) bool) |
| 95 | +``` |
| 96 | + |
| 97 | +### `container/set` 包 |
| 98 | + |
| 99 | +该包基于这些提案: |
| 100 | + |
| 101 | +- [golang/go#47331](https://golang.org/issue/47331) proposal: container/set: new package to provide a generic set type (discussion) |
| 102 | + |
| 103 | +可以在[这里](./std/container/set)找到一个可能的实现。 |
| 104 | + |
| 105 | +```go |
| 106 | +package set |
| 107 | + |
| 108 | +type Set[Elem comparable] struct { ... } |
| 109 | +func (s *Set[Elem]) Add(v ...Elem) |
| 110 | +func (s *Set[Elem]) AddSet(s2 Set[Elem]) |
| 111 | +func (s *Set[Elem]) Remove(v ...Elem) |
| 112 | +func (s *Set[Elem]) RemoveSet(s2 Set[Elem]) |
| 113 | +func (s *Set[Elem]) Has(v Elem) bool |
| 114 | +func (s *Set[Elem]) HasAny(s2 Set[Elem]) bool |
| 115 | +func (s *Set[Elem]) HasAll(s2 Set[Elem]) bool |
| 116 | +func (s *Set[Elem]) Values() []Elem |
| 117 | +func (s *Set[Elem]) Equal(s2 Set[Elem]) bool |
| 118 | +func (s *Set[Elem]) Clear() |
| 119 | +func (s *Set[Elem]) Clone() Set[Elem] |
| 120 | +func (s *Set[Elem]) Filter(keep func(Elem) bool) |
| 121 | +func (s *Set[Elem]) Len() int |
| 122 | +func (s *Set[Elem]) Do(f func(Elem) bool) |
| 123 | + |
| 124 | +func Of[Elem comparable](v ...Elem) Set[Elem] |
| 125 | +func Union[Elem comparable](s1, s2 Set[Elem]) Set[Elem] |
| 126 | +func Intersection[Elem comparable](s1, s2 Set[Elem]) Set[Elem] |
| 127 | +func Difference[Elem comparable](s1, s2 Set[Elem]) Set[Elem] |
| 128 | +``` |
| 129 | + |
| 130 | +### 其他 (仍在讨论中) |
| 131 | + |
| 132 | +- [golang/go#47657](https://golang.org/issue/47657) proposal: sync, sync/atomic: add PoolOf, MapOf, ValueOf |
| 133 | +- [golang/go#47632](https://golang.org/issue/47632) proposal: container/heap: add Heap, a heap backed by a slice |
| 134 | +- [golang/go#47619](https://golang.org/issue/47619) proposal: generic functions in the sort package |
| 135 | + |
| 136 | +## 更多示例 |
| 137 | + |
| 138 | +出了前面的标准库实现示例之外,仓库中还包含了更多其他场景下的的示例。这些示例可以直接 |
| 139 | +通过安装的 gotip 命令执行: |
| 140 | + |
| 141 | +``` |
| 142 | +$ gotip run demo/ex1-sort.go |
| 143 | +$ gotip run demo/ex2-mapreduce.go |
| 144 | +$ gotip run demo/ex3-stack.go |
| 145 | +$ gotip run demo/ex4-map.go |
| 146 | +$ cd errors && gotip test |
| 147 | +$ cd fmt && gotip test |
| 148 | +$ cd future && gotip test |
| 149 | +$ cd linalg && gotip test |
| 150 | +$ cd list && gotip test |
| 151 | +$ cd math && gotip test |
| 152 | +$ cd metrics && gotip test |
| 153 | +$ cd ring && gotip test |
| 154 | +$ cd stack && gotip test |
| 155 | +$ cd strings && gotip test |
| 156 | +$ cd sync/atomic && gotip test |
| 157 | +$ cd tree && gotip test |
| 158 | +``` |
| 159 | + |
| 160 | +## 已知的问题 |
| 161 | + |
| 162 | +由于当前 Go 的编译器实现上不完整,目前(2021.08.22)已知这些问题: |
| 163 | + |
| 164 | +- 泛型切片表达式尚未实现 |
| 165 | +- 公开函数的导出和包的导入还需要完善 |
| 166 | +- 更多类型检查相关的完善 |
| 167 | + |
| 168 | +更多满足语言规范的代码(暂时)还不能正常编译执行。例如这些目录下的代码: |
| 169 | + |
| 170 | +``` |
| 171 | +chans |
| 172 | +demo/ex5-loadbalance.go |
| 173 | +graph |
| 174 | +maps |
| 175 | +sched |
| 176 | +slices |
| 177 | +sync |
| 178 | +``` |
| 179 | + |
| 180 | +## 进一步阅读 |
| 181 | + |
| 182 | +- Changkun Ou. [Go 语言泛型研究总结](./generics.md). 2020.08. 最后更新 2021.08. |
| 183 | +- Changkun Ou. [Go 2 泛型: 类型参数](https://changkun.de/s/go2generics/). [Go 夜读 第 80 期](https://talkgo.org). 2020 年 3 月 18 日. |
| 184 | + |
| 185 | +## 许可 |
| 186 | + |
| 187 | +BSD-2-Clause |
| 188 | + |
| 189 | +Copyright © 2020-2021 [Changkun Ou](https://changkun.de) |
0 commit comments