瀏覽代碼

2022-03-29

qinghe 3 年之前
父節點
當前提交
32b6c7a9bd
共有 6 個文件被更改,包括 168 次插入7 次删除
  1. 4
    4
      chapter1-why-generics.slide
  2. 53
    1
      chapter3-others-about-generics.slide
  3. 3
    1
      codes/atomic.go
  4. 21
    0
      codes/type_assertion.go
  5. 74
    1
      codes/type_sets.go
  6. 13
    0
      codes/zero_value.go

+ 4
- 4
chapter1-why-generics.slide 查看文件

@@ -1,8 +1,8 @@
1 1
 # Go 泛型介绍
2 2
 
3 3
 清和
4
-2022-01-22
5
-chenqh721@foxmail.com
4
+2022-03-31
5
+qinghe.chen@tuya.com
6 6
 
7 7
 
8 8
 ## Agenda
@@ -28,11 +28,11 @@ chenqh721@foxmail.com
28 28
 - 类型转换影响性能
29 29
 
30 30
 
31
-## Type parameters
31
+## How Generics
32 32
 
33 33
 ## Type parameters
34 34
 
35
-泛型代码中会用到抽象的数据类型,这个类型叫做`type parameters`. 在运行泛型代码的时候,类型形参会被替换为类型实参。
35
+泛型代码中会用到抽象的数据类型,这个类型叫做`type parameters`(类型参数). 在运行泛型代码的时候,类型形参会被替换为类型实参。
36 36
 
37 37
 .code codes/print.go /PRINT OMIT/,/PRINT OMIT/
38 38
 

+ 53
- 1
chapter3-others-about-generics.slide 查看文件

@@ -65,8 +65,60 @@ Qinghe
65 65
 
66 66
 ## Type sets of embedded constraints
67 67
 
68
+.code codes/type_sets.go /EMBED INTERSECTION OMIT/,/EMBED INTERSECTION OMIT/
69
+
70
+
71
+
72
+## Type sets of embedded constraints
73
+.code codes/type_sets.go /EMBED UNION OMIT/,/EMBED UNION OMIT/
68 74
 
69 75
 ## Interface types in union elements
70 76
 
77
+.code codes/type_sets.go /INTERFACE IN UNION OMIT/,/INTERFACE IN UNION OMIT/
78
+
79
+- 约束的类型集包括string类型以及实现了fmt.Stringer接口的所有类型
80
+- 除所有类型都共有的操作外,无其他特殊的允许的操作
81
+- 必须通过断言或者反射来使用对应的值
82
+
83
+目前版本还未实现,see [issue#49054](https://github.com/golang/go/issues/49054),[issue#45346 (comment)](https://github.com/golang/go/issues/45346#issuecomment-862505803)
84
+
85
+## Empty type sets
86
+
87
+.code codes/type_sets.go /EMPTY TYPE SETS OMIT/,/EMPTY TYPE SETS OMIT/
88
+
89
+- 可以正常编译,但无法实例化
90
+- go vet 对某些能够被检测出来的情况“应该”报出错误
91
+
92
+
93
+## Some Issues
94
+
95
+
96
+## The zero value
97
+
98
+.code codes/zero_value.go /ZERO VALUE OMIT/,/ZERO VALUE OMIT/
99
+
100
+一些可行的方案:
101
+
102
+- 使用`var zero T; return zero`,与现行方案不冲突,但是需要额外的代码
103
+- 使用`return *new(T)`,语法比较奇怪,但是也能正常执行
104
+- 使用命名返回值,返回值用return即可返回零值。此种方案仅对在返回值中生效
105
+- 允许使用nil作为参数类型的零值返回
106
+- 允许使用T{}作为参数类型的零值返回
107
+- 允许在赋值语句(包括return以及函数调用)的右边使用`_`作为零值
108
+- 允许使用`return ...`来返回对应类型的零值
109
+
110
+
111
+## Identifying the matched predeclared type
112
+
113
+.code codes/type_assertion.go /TYPE ASSERTION OMIT/,/TYPE ASSERTION OMIT/
114
+
115
+并不想知道v的真实类型,只想知道v的底层是float32还是float64,但目前无法做到。
116
+
117
+一种解决方法是扩展switch case语法,支持`case ~float32:`类型的语句,甚至在泛型函数之外也应该可以使用这样的语法。
118
+
119
+
120
+## No parameterized methods
121
+(略)
71 122
 
72
-## Empty type sets
123
+## No way to require pointer methods
124
+(略)

+ 3
- 1
codes/atomic.go 查看文件

@@ -1,6 +1,8 @@
1
-package example
1
+package main
2 2
 
3 3
 // OMIT
4
+package atomic 
5
+
4 6
 func AddInt32(addr *int32, delta int32) int32 {
5 7
 	// some codes ...
6 8
 	return 0

+ 21
- 0
codes/type_assertion.go 查看文件

@@ -0,0 +1,21 @@
1
+package main
2
+
3
+
4
+// TYPE ASSERTION OMIT
5
+func NewtonSqrt[T ~float32 | ~float64 ](v T) T {
6
+	var iterations int
7
+	switch (interface{})(v).(type) {
8
+	case float32:
9
+		iterations = 4
10
+	case float64:
11
+		iterations = 5
12
+	default:
13
+		panic(fmt.Sprintf("unexpected type %T", v))
14
+	}
15
+	// Code omitted.
16
+}
17
+
18
+type MyFloat float32
19
+
20
+var G = NewtonSqrt(MyFloat(64))
21
+// TYPE ASSERTION OMIT

+ 74
- 1
codes/type_sets.go 查看文件

@@ -154,4 +154,77 @@ func Add1024[T integer](s []T) {
154 154
 		s[i] = v + 1024 // INVALID: 1024 not permitted by int8/uint8
155 155
 	}
156 156
 }
157
-// UNTYPED CONSTANTS OMIT
157
+// UNTYPED CONSTANTS OMIT
158
+
159
+
160
+// EMBED INTERSECTION OMIT
161
+// Addable is types that support the + operator.
162
+type Addable interface {
163
+	~int | ~int8 | ~int16 | ~int32 | ~int64 |
164
+		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
165
+		~float32 | ~float64 | ~complex64 | ~complex128 |
166
+		~string
167
+}
168
+
169
+// Byteseq is a byte sequence: either string or []byte.
170
+type Byteseq interface {
171
+	~string | ~[]byte
172
+}
173
+
174
+// AddableByteseq is a byte sequence that supports +.
175
+// This is every type that is both Addable and Byteseq.
176
+// In other words, just the type set ~string.
177
+type AddableByteseq interface {
178
+	Addable
179
+	Byteseq
180
+}
181
+// EMBED INTERSECTION OMIT
182
+
183
+
184
+
185
+// EMBED UNION OMIT
186
+// Signed is a constraint with a type set of all signed integer
187
+// types.
188
+type Signed interface {
189
+	~int | ~int8 | ~int16 | ~int32 | ~int64
190
+}
191
+
192
+// Unsigned is a constraint with a type set of all unsigned integer
193
+// types.
194
+type Unsigned interface {
195
+	~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
196
+}
197
+
198
+// Integer is a constraint with a type set of all integer types.
199
+type Integer interface {
200
+	Signed | Unsigned
201
+}
202
+// EMBED UNION OMIT
203
+
204
+// INTERFACE IN UNION OMIT
205
+type Stringish interface {
206
+	string | fmt.Stringer
207
+}
208
+
209
+func ToString[T Stringish](v T) string {
210
+	switch x := (interface{})(v).(type) {
211
+	case string:
212
+	  return x
213
+  
214
+	case fmt.Stringer:
215
+	  return x.String()
216
+	}
217
+  
218
+	panic("impossible")
219
+  }
220
+// INTERFACE IN UNION OMIT
221
+
222
+// EMPTY TYPE SETS OMIT
223
+// Unsatisfiable is an unsatisfiable constraint with an empty type set.
224
+// No predeclared types have any methods.
225
+// If this used ~int | ~float32 the type set would not be empty.
226
+type Unsatisfiable interface {
227
+	int | float32
228
+	String() string
229
+}
230
+// EMPTY TYPE SETS OMIT

+ 13
- 0
codes/zero_value.go 查看文件

@@ -0,0 +1,13 @@
1
+package main
2
+
3
+
4
+// ZERO VALUE OMIT
5
+type Optional[T any] struct { p *T }
6
+func (o Optional[T]) Val() T {
7
+	if o.p != nil {
8
+		return *o.p
9
+	}
10
+	// how do we return default value of type T ?
11
+}
12
+
13
+// ZERO VALUE OMIT