qinghe vor 3 Jahren
Ursprung
Commit
c69594e681
5 geänderte Dateien mit 135 neuen und 3 gelöschten Zeilen
  1. 67
    1
      chapter2-constraints.slide
  2. 21
    0
      chapter3-others-about-generics.slide
  3. 6
    0
      codes/print.go
  4. 32
    1
      codes/type_inference.go
  5. 9
    1
      codes/type_sets.go

+ 67
- 1
chapter2-constraints.slide Datei anzeigen

@@ -275,4 +275,70 @@ comparable作为一个约束,它也可以被嵌入在其他约束内。
275 275
 
276 276
 
277 277
 ## Function argument type inference
278
-函数参数类型推断用在进行函数调用并且没有指明类型参数时。当类型参数在实例化
278
+函数参数类型推断用在进行函数调用但是没有指明类型参数的时候。类型参数的值可以通过非类型参数的类型来推断出来。
279
+
280
+仅当类型参数被用在函数的入参时,类型参数可以被推断。如果类型参数作为函数出参的类型,或者仅在函数内部使用时,无法进行推断。
281
+
282
+以下函数的类型参数就无法通过函数参数类型推断来推断:
283
+
284
+.code codes/type_inference.go /CANNOT INFERENCE OMIT/,/CANNOT INFERENCE OMIT/
285
+
286
+## Function argument type inference
287
+
288
+以之前的例子介绍类型推断过程:
289
+
290
+.code codes/print.go /CALL TYPE OMIT/,/CALL TYPE OMIT/
291
+
292
+要推断类型参数的值,我们需要对函数普通参数的类型和函数的类型参数进行归并。从调用方的角度,我们知道普通函数参数的类型,在上面的例子中就是[]int。
293
+在函数定义的角度,我们知道函数的参数类型是[]T。
294
+
295
+[]int可以与类型[]T进行归并,并且此时T的类型是int。因此可以推断出类型参数的值实际上是int。即完整的调用应该是
296
+
297
+.code codes/print.go /COMPLETE CALL OMIT/,/COMPLETE CALL OMIT/
298
+
299
+## Function argument type inference
300
+
301
+函数参数类型推断分为两步进行。
302
+
303
+0. 首先忽略调用方传入的未定义类型常量以及在函数定义中对应的类型,这些常量的类型会在后面的步骤进行确定。
304
+
305
+1. 对剩余的类型进行归并处理,会得到函数类型参数和实参类型的对应关系,如果类型参数在函数中出现多次,那么可能会匹配到多个对应关系,如果相同的类型参数对应的实参类型不同,则报错。
306
+
307
+2. 经过第一步的处理后,如果没有未定义类型常量,或者类型参数都和普通参数的入参类型一一对应,则归并完成。如果还有未定义类型常量及对应的类型参数,则常量的类型为默认的类型,然后再对剩余类型继续进行归并。 
308
+
309
+
310
+## Function argument type inference
311
+
312
+以一个稍微复杂点的例子来说明类型推断过程:
313
+
314
+.code codes/type_inference.go /MAP2 OMIT/,/MAP2 OMIT/
315
+
316
+1. 归并[]int和[]F => F = int 
317
+2. 归并`func(int) string`和`func(F) T` => F = int, T = string 
318
+3. 类型参数F匹配了两次,因为两次匹配到的类型相同,都是int,因此归并成功。
319
+4. 可以推导出完整的函数调用应该是`Map[int,string]`
320
+
321
+## Function argument type inference
322
+
323
+参数包括未定义类型常量的示例:
324
+
325
+.code codes/type_inference.go /PAIR OMIT/,/PAIR OMIT/
326
+
327
+
328
+- NewPair(1, 2)  => `NewPair[int](1,2)`
329
+- NewPair(1, int64(2)) => `NewPair[int64](1,int64(2))`
330
+- NewPair(2, 2.5) => `compilation error`
331
+
332
+
333
+
334
+## Constraint type inference (约束类型推断)
335
+
336
+
337
+
338
+## Constraint type inference
339
+
340
+约束类型推断可以基于类型参数约束来从一个类型参数中推断另外一个类型参数的值。
341
+
342
+略
343
+
344
+

+ 21
- 0
chapter3-others-about-generics.slide Datei anzeigen

@@ -0,0 +1,21 @@
1
+
2
+# More on type sets
3
+Qinghe
4
+21 Jan 2022
5
+
6
+
7
+## Both elements and methods in constraints
8
+约束中可以同时约束元素(具体类型、近似类型、联合类型)和方法。
9
+
10
+.code codes/type_sets.go /StringableSignedInteger OMIT/,/StringableSignedInteger OMIT/
11
+
12
+满足这个约束的类型必须满足两个条件:
13
+1. 底层类型是int/int8/int16/int32/int64类型其中之一
14
+2. 这个类型必须有`String() string`方法
15
+
16
+要注意:
17
+
18
+`'~'`符号是必要的,因为int类型本身没有实现`String() string`方法
19
+
20
+## Composite types in constraints
21
+

+ 6
- 0
codes/print.go Datei anzeigen

@@ -28,4 +28,10 @@ func main(){
28 28
 	Print[int]([]int{1,2,3,4})
29 29
 	Print[int32](int32{1,2,3,4})
30 30
 	// CALL OMIT
31
+	// CALL TYPE OMIT
32
+	Print([]int{1,2,3})
33
+	// CALL TYPE OMIT
34
+	// COMPLETE CALL OMIT
35
+	Print[int]([]int{1,2,3})
36
+	// COMPLETE CALL OMIT
31 37
 }

+ 32
- 1
codes/type_inference.go Datei anzeigen

@@ -27,4 +27,35 @@ func Double[T interface{ ~int }](v T) T {
27 27
 
28 28
 Double(1) // 
29 29
 
30
-// ERR OMIT
30
+// ERR OMIT
31
+
32
+
33
+// CANNOT INFERENCE OMIT
34
+
35
+func NewValue[T any]()T {
36
+	var t T 
37
+	return t 
38
+}
39
+
40
+println(NewValue()) // cannot infer T
41
+// CANNOT INFERENCE OMIT
42
+
43
+
44
+// MAP2 OMIT
45
+// Map calls the function f on every element of the slice s,
46
+// returning a new slice of the results.
47
+func Map[F, T any](s []F, f func(F) T) []T {
48
+	r := make([]T, len(s))
49
+	for i, v := range s {
50
+		r[i] = f(v)
51
+	}
52
+	return r
53
+}
54
+
55
+strs := Map([]int{1, 2, 3}, strconv.Itoa)
56
+// MAP2 OMIT
57
+
58
+// PAIR OMIT
59
+// NewPair returns a pair of values of the same type.
60
+func NewPair[F any](f1, f2 F) *Pair[F] { ... }
61
+// PAIR OMIT

+ 9
- 1
codes/type_sets.go Datei anzeigen

@@ -63,4 +63,12 @@ type SignedInteger interface {
63 63
 	~int | ~int8 | ~int16 | ~int32 | ~int64
64 64
 }
65 65
 
66
-// ONION EXAMPLE OMIT
66
+// ONION EXAMPLE OMIT
67
+
68
+
69
+// StringableSignedInteger OMIT
70
+type StringableSignedInteger interface {
71
+	~int | ~int8 | ~int16 | ~int32 | ~int64
72
+	String() string
73
+}
74
+// StringableSignedInteger OMIT