package main import "fmt" // a generic function that takes a slice of any type and a value of that type, and returns the index of the value in the slice, or -1 if it is not found. // The type parameters S and E are declared in square brackets before the function name, and they can be used in the function signature and body. // The constraint comparable means that the type E must support the == operator, which is necessary for comparing the value with the elements of the slice. func SlicesIndex[S []E, E comparable](s S, v E) int { for i := range s { if v == s[i] { return i } } return -1 } // represents a linked list of any type T. The type parameter T is used in the definition of List and its methods, // and it can be instantiated with any type when we create a List value. The type any is in fact defined as // an empty interface. Thanks to duck-typing it can be used to represent any type, but it does not provide any // operations on the values of that type. type List[T any] struct { head, tail *element[T] } // the generic element of the linked list type element[T any] struct { next *element[T] val T } // adds an instance of the generic type to the list func (lst *List[T]) Push(v T) { if lst.tail == nil { lst.head = &element[T]{val: v} lst.tail = lst.head } else { lst.tail.next = &element[T]{val: v} lst.tail = lst.tail.next } } // returns all elements of the list as a slice of the generic type. func (lst List[T]) AllElements() []T { var elems []T for e := lst.head; e != nil; e = e.next { elems = append(elems, e.val) } return elems } func main() { var s = []string{"foo", "bar", "zoo"} // The types S and E are explicitly specified as []string and string respectively. fmt.Println("index of zoo:", SlicesIndex[[]string, string](s, "zoo")) var s2 = []int{2, 4, 5, 6} // The type E is inferred from the type of the value 4, which is int, // and the type S is inferred from the type of the slice s2, which is []int. fmt.Println("index of 4: ", SlicesIndex(s2, 4)) // instantiate a list of float64 elements lst := List[float64]{} lst.Push(10) lst.Push(13) lst.Push(23) lst.Push(23.3) fmt.Println("list:", lst.AllElements()) }