瀏覽代碼

2022-03-28

qinghe 3 年之前
父節點
當前提交
ff67d24967
共有 2 個文件被更改,包括 136 次插入2 次删除
  1. 52
    1
      chapter3-others-about-generics.slide
  2. 84
    1
      codes/type_sets.go

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

@@ -15,7 +15,58 @@ Qinghe
15 15
 
16 16
 要注意:
17 17
 
18
-`'~'`符号是必要的,因为int类型本身没有实现`String() string`方法
18
+`'~'`符号是必要的,因为int类型本身没有实现`String() string`方法,否则语法检查能通过,但是满足条件的类型集合为空。
19 19
 
20 20
 ## Composite types in constraints
21 21
 
22
+复合类型包括以下几种:
23
+
24
+- string
25
+- pointer
26
+- array 
27
+- slice 
28
+- struct 
29
+- function 
30
+- map 
31
+- channel 
32
+
33
+## Composite types in constraints
34
+
35
+在约束中使用复合类型:
36
+
37
+.code codes/type_sets.go /COMPOSITE TYPE OMIT/,/COMPOSITE TYPE OMIT/
38
+
39
+## Composite types in constraints
40
+
41
+对于复合类型的使用,有个额外的限制:对于所有的类型集中的类型,只有输入以及输出类型均完全一致的操作才允许使用。
42
+
43
+例如:
44
+
45
+.code codes/type_sets.go /COMPOSITE STRUCT FIELD OMIT/,/COMPOSITE STRUCT FIELD OMIT/
46
+
47
+(当然目前即使上面例子中各个struct的x字段类型一致也无法执行,因为这个特性在1.18中已经被移除,后续版本中可能会加回来,详情见[issue#50417](https://github.com/golang/go/issues/50417)、[issue#51576](https://github.com/golang/go/issues/51576))
48
+
49
+
50
+
51
+## Type conversions
52
+
53
+如果要对两个类型参数From和To类型的变量进行类型转换,则需要From的约束所包含的所有类型均能够转换为To的约束所包含的任一类型。
54
+
55
+例如:
56
+
57
+.code codes/type_sets.go /TYPE CONVERSION OMIT/,/TYPE CONVERSION OMIT/
58
+
59
+
60
+## Untyped constants
61
+泛型函数中可能会使用到无类型常量,在使用无类型常量的时候,仅当约束中所包含的所有类型都可以正常使用无类型常量。
62
+
63
+.code codes/type_sets.go /UNTYPED CONSTANTS OMIT/,/UNTYPED CONSTANTS OMIT/
64
+
65
+
66
+## Type sets of embedded constraints
67
+
68
+
69
+## Interface types in union elements
70
+
71
+
72
+## Empty type sets

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

@@ -71,4 +71,87 @@ type StringableSignedInteger interface {
71 71
 	~int | ~int8 | ~int16 | ~int32 | ~int64
72 72
 	String() string
73 73
 }
74
-// StringableSignedInteger OMIT
74
+// StringableSignedInteger OMIT
75
+
76
+
77
+// COMPOSITE TYPE OMIT
78
+type byteseq interface{
79
+	string | []byte
80
+}
81
+
82
+func Join[T byteseq](a []T, sep T) (ret T) {
83
+	// some checks...
84
+	
85
+	n := len(sep) * (len(a) - 1)
86
+	for _, v := range a {
87
+		n += len(v)
88
+	}
89
+
90
+	b := make([]byte, n)
91
+
92
+	bp := copy(b, a[0])
93
+	for _, s := range a[1:] {
94
+		bp += copy(b[bp:], sep)
95
+		bp += copy(b[bp:], s)
96
+	}
97
+
98
+	return T(b)
99
+}
100
+// COMPOSITE TYPE OMIT
101
+
102
+
103
+// COMPOSITE STRUCT FIELD OMIT
104
+// structField is a type constraint whose type set consists of some
105
+// struct types that all have a field named x.
106
+type structField interface {
107
+	struct { a int; x int } |
108
+		struct { b int; x float64 } |
109
+		struct { c int; x uint64 }
110
+}
111
+
112
+// This function is INVALID.
113
+func IncrementX[T structField](p *T) {
114
+	v := p.x // INVALID: type of p.x is not the same for all types in set
115
+	v++
116
+	p.x = v
117
+}
118
+// COMPOSITE STRUCT FIELD OMIT
119
+
120
+
121
+
122
+// TYPE CONVERSION OMIT
123
+type integer interface {
124
+	~int | ~int8 | ~int16 | ~int32 | ~int64 |
125
+		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
126
+}
127
+
128
+func Convert[To, From integer](from From) To {
129
+	to := To(from)
130
+	if From(to) != from {
131
+		panic("conversion out of range")
132
+	}
133
+	return to
134
+}
135
+
136
+// TYPE CONVERSION OMIT
137
+
138
+
139
+// UNTYPED CONSTANTS OMIT
140
+type integer interface {
141
+	~int | ~int8 | ~int16 | ~int32 | ~int64 |
142
+		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
143
+}
144
+
145
+func Add10[T integer](s []T) {
146
+	for i, v := range s {
147
+		s[i] = v + 10 // OK: 10 can convert to any integer type
148
+	}
149
+}
150
+
151
+// This function is INVALID.
152
+func Add1024[T integer](s []T) {
153
+	for i, v := range s {
154
+		s[i] = v + 1024 // INVALID: 1024 not permitted by int8/uint8
155
+	}
156
+}
157
+// UNTYPED CONSTANTS OMIT