~/snippets/go-generics
Published on

Generics in Go

478 words3 min read

Percent function that can work with either int or float64 types.

func Percent[T int | float64](percent T, number T) float64 {
	return ((float64(number) * float64(percent)) / float64(100))
}

ArePointersEqual function that determines if two pointers are equal. Only works with either int or string types.

func ArePointersEqual[T int | string](a *T, b *T) bool {
	return a == nil && b == nil || a != nil && b != nil && *a == *b
}

Convert to and from pointers

func ToPointer[T any](t T) *T {
	return &t
}

func FromPointer[T any](t *T) T {
	if t == nil {
		return *new(T)
	}
	return *t
}

Copy a pointer to a slice to a different memory address

package main

import "fmt"

func main() {
	s := []string{"hello", "world", "foo", "bar"}
	ss := &s

	fmt.Printf("Memory Address Before: (ss: %p) \n", ss)
	fmt.Printf("Contents: (ss: %+v)\n", ss)

	cs := CopyPtrSlice(ss)
	// cs := ss // Uncomment this line and you'll see that the append to cs also changes ss

	fmt.Printf("Memory Address Before: (ss: %p) (cs: %p) \n", ss, cs)
	fmt.Printf("Contents: (ss: %+v) (cs: %+v) \n", ss, cs)

	*cs = append(*cs, "wibble")

	fmt.Printf("Contents: (ss: %+v) (cs: %+v) \n", ss, cs)

}

func CopyPtrSlice[T any](in *[]T) *[]T {
	out := make([]T, len(*in))
	copy(out, *in)

	return &out
}