Skip to content

Instantly share code, notes, and snippets.

@letschers
Created April 13, 2024 17:32
Show Gist options
  • Select an option

  • Save letschers/50ff71b9b1716d17d07616d292d707f9 to your computer and use it in GitHub Desktop.

Select an option

Save letschers/50ff71b9b1716d17d07616d292d707f9 to your computer and use it in GitHub Desktop.
Golang generics sucks
package main
import (
"fmt"
"reflect"
"slices"
"strings"
)
type Obj[K any, V comparable] struct {
key K
value V
}
func compareValues[T comparable](a, b T) int {
var (
valueA = reflect.ValueOf(a)
valueB = reflect.ValueOf(b)
)
if valueA.Type() != valueB.Type() {
panic("types are not comparable")
}
switch valueA.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
if valueA.Int() < valueB.Int() {
return -1
} else if valueA.Int() > valueB.Int() {
return 1
} else {
return 0
}
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
if valueA.Uint() < valueB.Uint() {
return -1
} else if valueA.Uint() > valueB.Uint() {
return 1
} else {
return 0
}
case reflect.Float32, reflect.Float64:
if valueA.Float() < valueB.Float() {
return -1
} else if valueA.Float() > valueB.Float() {
return 1
} else {
return 0
}
case reflect.String:
return strings.Compare(valueA.String(), valueB.String())
default:
panic("unsupported type")
}
}
func sortFunc[K, V comparable](obj1, obj2 Obj[K, V]) int {
return compareValues(obj1.value, obj2.value)
}
type ObjArr[K comparable, V comparable] []Obj[K, V]
func (a ObjArr[K, V]) Sort() {
slices.SortFunc(a, sortFunc)
}
func mapToSlice[K, V comparable](m map[K]V) ObjArr[K, V] {
var slice []Obj[K, V]
for k, v := range m {
slice = append(slice, Obj[K, V]{
key: k,
value: v,
})
}
return slice
}
func sliceToMap[K, V comparable](s ObjArr[K, V]) map[K]V {
var m = make(map[K]V)
for _, v := range s {
m[v.key] = v.value
}
return m
}
func main() {
var m = map[string]int{
"second": 2,
"forth": 4,
"first": 1,
"third": 3,
"fifth": 5,
}
var s = mapToSlice(m)
fmt.Println(s) // [{second 2} {forth 4} {first 1} {third 3} {fifth 5}]
s.Sort()
fmt.Println(s) // [{first 1} {second 2} {third 3} {forth 4} {fifth 5}]
var m2 = map[string]string{
"second": "b",
"forth": "d",
"first": "a",
"third": "c",
"fifth": "e",
}
var s2 = mapToSlice(m2)
fmt.Println(s2) // [{second b} {forth d} {first a} {third c} {fifth e}]
s2.Sort()
fmt.Println(s2) // [{first a} {second b} {third c} {forth d} {fifth e}]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment