1 // Copyright 2021 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // This file shows some examples of type inference.
6
7 package p
8
9 type Ordered interface {
10 ~int|~float64|~string
11 }
12
13 func min[T Ordered](x, y T) T { panic(0) }
14
15 func _() {
16 // min can be called with explicit instantiation.
17 _ = min[int](1, 2)
18
19 // Alternatively, the type argument can be inferred from
20 // one of the arguments. Untyped arguments will be considered
21 // last.
22 var x int
23 _ = min(x, x)
24 _ = min(x, 1)
25 _ = min(x, 1.0)
26 _ = min(1, 2)
27 _ = min(1, 2.3 /* ERROR default type float64 .* does not match */ )
28
29 var y float64
30 _ = min(1, y)
31 _ = min(1.2, y)
32 _ = min(1.2, 3.4)
33 _ = min(1.2, 3 /* ERROR default type int .* does not match */ )
34
35 var s string
36 _ = min(s, "foo")
37 _ = min("foo", "bar")
38 }
39
40 func mixed[T1, T2, T3 any](T1, T2, T3) {}
41
42 func _() {
43 // mixed can be called with explicit instantiation.
44 mixed[int, string, bool](0, "", false)
45
46 // Alternatively, partial type arguments may be provided
47 // (from left to right), and the other may be inferred.
48 mixed[int, string](0, "", false)
49 mixed[int](0, "", false)
50 mixed(0, "", false)
51
52 // Provided type arguments always take precedence over
53 // inferred types.
54 mixed[int, string](1.1 /* ERROR cannot use 1.1 */ , "", false)
55 }
56
57 func related1[Slice interface{~[]Elem}, Elem any](s Slice, e Elem) {}
58
59 func _() {
60 // related1 can be called with explicit instantiation.
61 var si []int
62 related1[[]int, int](si, 0)
63
64 // Alternatively, the 2nd type argument can be inferred
65 // from the first one through constraint type inference.
66 var ss []string
67 _ = related1[[]string]
68 related1[[]string](ss, "foo")
69
70 // A type argument inferred from another explicitly provided
71 // type argument overrides whatever value argument type is given.
72 related1[[]string](ss, 0 /* ERROR cannot use 0 */ )
73
74 // A type argument may be inferred from a value argument
75 // and then help infer another type argument via constraint
76 // type inference.
77 related1(si, 0)
78 related1(si, "foo" /* ERROR cannot use "foo" */ )
79 }
80
81 func related2[Elem any, Slice interface{[]Elem}](e Elem, s Slice) {}
82
83 func _() {
84 // related2 can be called with explicit instantiation.
85 var si []int
86 related2[int, []int](0, si)
87
88 // Alternatively, the 2nd type argument can be inferred
89 // from the first one through constraint type inference.
90 var ss []string
91 _ = related2[string]
92 related2[string]("foo", ss)
93
94 // A type argument may be inferred from a value argument
95 // and then help infer another type argument via constraint
96 // type inference. Untyped arguments are always considered
97 // last.
98 related2(1.2, []float64{})
99 related2(1.0, []int{})
100 related2 /* ERROR does not implement */ (float64(1.0), []int{}) // TODO(gri) fix error position
101 }
102
103 type List[P any] []P
104
105 func related3[Elem any, Slice []Elem | List[Elem]]() Slice { return nil }
106
107 func _() {
108 // related3 can be instantiated explicitly
109 related3[int, []int]()
110 related3[byte, List[byte]]()
111
112 // The 2nd type argument cannot be inferred from the first
113 // one because there's two possible choices: []Elem and
114 // List[Elem].
115 related3 /* ERROR cannot infer Slice */ [int]()
116 }
117
View as plain text