any (interface{}) and downcasting) with static typing (type parameters)// simple generic "map" function
func Map[F, T any](s []F, f func(F) T) []T {
r := make([]T, len(s))
for i, v := range s {
r[i] = f(v)
}
return r
}
<>
type Vector[T any] []T
// generic Push function for this new generic vector type
// it takes in a pointer because append() might reallocate, so without
// a pointer the reallocation would basically just be lost and nothing would result
func (v *Vector[T]) Push(x T) {
*v = append(*v, x)
}
func main() {
s := Vector[int]{}
s.Push(1)
s.Push(2)
// using our Map function on the Vector type
t1 := Map(s, strconv.Itoa)
}
Map are both used in the formal parameters, we don’t need to explicitly pass these type parameters in the call to Map shown above
Map[int, string](...))type StringableVector[T fmt.Stringer] []T // our type T has to conform to the Stringer interface (implement String())
type num int
func (n num) String() {
return strconv.Itoa(int(n)) // cast our type (this is fine since the underlying type of num is int)
}
func main() {
var s StringableVector[num] = []num{1,2,3}
fmt.Println(s)
}
interface{}, casting etc.) for type safety at compile time