|
@@ -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
|
+
|