@@ -5,20 +5,22 @@ package main
5
5
6
6
import "fmt"
7
7
8
- // As an example of a generic function, `MapKeys` takes
9
- // a map of any type and returns a slice of its keys.
10
- // This function has two type parameters - `K` and `V`;
11
- // `K` has the `comparable` _constraint_, meaning that
12
- // we can compare values of this type with the `==` and
13
- // `!=` operators. This is required for map keys in Go.
14
- // `V` has the `any` constraint, meaning that it's not
15
- // restricted in any way (`any` is an alias for `interface{}`).
16
- func MapKeys [K comparable , V any ](m map [K ]V ) []K {
17
- r := make ([]K , 0 , len (m ))
18
- for k := range m {
19
- r = append (r , k )
8
+ // As an example of a generic function, `SlicesIndex` takes
9
+ // a slice of any `comparable` type and an element of that
10
+ // type and returns the index of the first occurrence of
11
+ // v in s, or -1 if not present. The `comparable` constraint
12
+ // means that we can compare values of this type with the
13
+ // `==` and `!=` operators. For a more thorough explanation
14
+ // of this type signature, see [this blog post](https://go.dev/blog/deconstructing-type-parameters).
15
+ // Note that this function exists in the standard library
16
+ // as [slices.Index](https://pkg.go.dev/slices#Index).
17
+ func SlicesIndex [S ~ []E , E comparable ](s S , v E ) int {
18
+ for i := range s {
19
+ if v == s [i ] {
20
+ return i
21
+ }
20
22
}
21
- return r
23
+ return - 1
22
24
}
23
25
24
26
// As an example of a generic type, `List` is a
@@ -45,7 +47,10 @@ func (lst *List[T]) Push(v T) {
45
47
}
46
48
}
47
49
48
- func (lst * List [T ]) GetAll () []T {
50
+ // AllElements returns all the List elements as a slice.
51
+ // In the next example we'll see a more idiomatic way
52
+ // of iterating over all elements of custom types.
53
+ func (lst * List [T ]) AllElements () []T {
49
54
var elems []T
50
55
for e := lst .head ; e != nil ; e = e .next {
51
56
elems = append (elems , e .val )
@@ -54,21 +59,21 @@ func (lst *List[T]) GetAll() []T {
54
59
}
55
60
56
61
func main () {
57
- var m = map [ int ]string {1 : "2 " , 2 : "4 " , 4 : "8 " }
62
+ var s = [ ]string {"foo " , "bar " , "zoo " }
58
63
59
64
// When invoking generic functions, we can often rely
60
65
// on _type inference_. Note that we don't have to
61
- // specify the types for `K ` and `V ` when
62
- // calling `MapKeys ` - the compiler infers them
66
+ // specify the types for `S ` and `E ` when
67
+ // calling `SlicesIndex ` - the compiler infers them
63
68
// automatically.
64
- fmt .Println ("keys :" , MapKeys ( m ))
69
+ fmt .Println ("index of zoo :" , SlicesIndex ( s , "zoo" ))
65
70
66
71
// ... though we could also specify them explicitly.
67
- _ = MapKeys [ int , string ](m )
72
+ _ = SlicesIndex [[] string , string ](s , "zoo" )
68
73
69
74
lst := List [int ]{}
70
75
lst .Push (10 )
71
76
lst .Push (13 )
72
77
lst .Push (23 )
73
- fmt .Println ("list:" , lst .GetAll ())
78
+ fmt .Println ("list:" , lst .AllElements ())
74
79
}
0 commit comments