Source file
test/typeparam/shape_assert.go
1
2
3
4
5
6
7
8
9
10
11 package main
12
13 import "fmt"
14
15 func switchStringOrBytes[S string | []byte](x S) string {
16 switch any(x).(type) {
17 case string:
18 return "string"
19 case []byte:
20 return "[]byte"
21 }
22 return "unknown"
23 }
24
25 func switchThree[S string | []byte | int](x S) string {
26 switch any(x).(type) {
27 case string:
28 return "string"
29 case []byte:
30 return "[]byte"
31 case int:
32 return "int"
33 }
34 return "unknown"
35 }
36
37 type MyString string
38
39 func switchNamed[S string | MyString](x S) string {
40 switch any(x).(type) {
41 case string:
42 return "string"
43 case MyString:
44 return "MyString"
45 }
46 return "unknown"
47 }
48
49 func commaOkString[S string | []byte](x S) (string, bool) {
50 v, ok := any(x).(string)
51 return v, ok
52 }
53
54 func commaOkBytes[S string | []byte](x S) ([]byte, bool) {
55 v, ok := any(x).([]byte)
56 return v, ok
57 }
58
59 func commaOkChain[S string | []byte | int](x S) string {
60 if _, ok := any(x).(string); ok {
61 return "string"
62 }
63 if _, ok := any(x).([]byte); ok {
64 return "[]byte"
65 }
66 if _, ok := any(x).(int); ok {
67 return "int"
68 }
69 return "unknown"
70 }
71
72
73 func commaOkViaVar[S string | []byte](x S) (string, bool) {
74 iface := any(x)
75 v, ok := iface.(string)
76 return v, ok
77 }
78
79 func switchViaVar[S string | []byte](x S) string {
80 iface := any(x)
81 switch iface.(type) {
82 case string:
83 return "string"
84 case []byte:
85 return "[]byte"
86 }
87 return "unknown"
88 }
89
90
91 func switchFallsToDefault[S string | []byte | int](x S) string {
92 switch any(x).(type) {
93 case string:
94 return "string"
95 case []byte:
96 return "[]byte"
97 }
98 return "other"
99 }
100
101 func main() {
102 check("switchStringOrBytes string", switchStringOrBytes("hello"), "string")
103 check("switchStringOrBytes []byte", switchStringOrBytes([]byte("hello")), "[]byte")
104
105 check("switchThree string", switchThree("x"), "string")
106 check("switchThree []byte", switchThree([]byte("x")), "[]byte")
107 check("switchThree int", switchThree(42), "int")
108
109 check("switchNamed string", switchNamed("hi"), "string")
110 check("switchNamed MyString", switchNamed(MyString("hi")), "MyString")
111
112 v1, ok1 := commaOkString("hello")
113 check("commaOkString[string] val", v1, "hello")
114 checkBool("commaOkString[string] ok", ok1, true)
115 v2, ok2 := commaOkString([]byte("hello"))
116 check("commaOkString[[]byte] val", v2, "")
117 checkBool("commaOkString[[]byte] ok", ok2, false)
118
119 v3, ok3 := commaOkBytes([]byte("world"))
120 check("commaOkBytes[[]byte] val", string(v3), "world")
121 checkBool("commaOkBytes[[]byte] ok", ok3, true)
122 v4, ok4 := commaOkBytes("world")
123 check("commaOkBytes[string] val", string(v4), "")
124 checkBool("commaOkBytes[string] ok", ok4, false)
125
126 check("commaOkChain string", commaOkChain("x"), "string")
127 check("commaOkChain []byte", commaOkChain([]byte("x")), "[]byte")
128 check("commaOkChain int", commaOkChain(42), "int")
129
130
131 v5, ok5 := commaOkViaVar("hello")
132 check("commaOkViaVar[string] val", v5, "hello")
133 checkBool("commaOkViaVar[string] ok", ok5, true)
134 v6, ok6 := commaOkViaVar([]byte("hello"))
135 check("commaOkViaVar[[]byte] val", v6, "")
136 checkBool("commaOkViaVar[[]byte] ok", ok6, false)
137
138
139 check("switchViaVar string", switchViaVar("x"), "string")
140 check("switchViaVar []byte", switchViaVar([]byte("x")), "[]byte")
141
142
143 check("switchFallsToDefault string", switchFallsToDefault("x"), "string")
144 check("switchFallsToDefault []byte", switchFallsToDefault([]byte("x")), "[]byte")
145 check("switchFallsToDefault int", switchFallsToDefault(42), "other")
146 }
147
148 func check(name, got, want string) {
149 if got != want {
150 panic(fmt.Sprintf("%s: got %q, want %q", name, got, want))
151 }
152 }
153
154 func checkBool(name string, got, want bool) {
155 if got != want {
156 panic(fmt.Sprintf("%s: got %v, want %v", name, got, want))
157 }
158 }
159
View as plain text