Search code examples
go

Passing a map with a custom type to a helper function in Go


I have a custom type

type MyType int

const (
    Type1 MyType = iota
) 

and a map

var myMap = map[string]MyType{}

I want to pass this map to a helper function

stringArray := MyHelper(MyType)

without the helper knowing the type by name

func MyHelper(inMap map[string]<what_here>???) []string {

}

This is kinda easy in other languages that I know using generics, but I can't figure this out in Go.

I have tried:

func MyHelper(inMap map[string]interface{}) []string { }
func MyHelper(inMap map[string]reflect.Type) []string { }

The errors: cannot use myType (variable of type map[string]myType) as map[string]invalid type

What will I do with it? Seriously? In this case I will create a string array from the keys in the map. In another I will create a map[string]string from the keys of two different maps of similar structure.

Basically guys, I just want a helper function that does this:

for k := range myMap {
    keys = append(keys, k)
}

where I can pass myMap to the function as a generic.

Just looking for someone who knows Go well enough to answer.


Solution

  • Work through “A Tour of Go”, then try

    package main
    
    import "fmt"
    
    type MyType int
    
    func main() {
        myMap := map[string]MyType{"hello": MyType(0), "world": MyType(1)}
        stringArray := MyHelper(myMap)
        fmt.Println(stringArray)
    }
    
    func MyHelper[T any](myMap map[string]T) []string {
        keys := make([]string, 0, len(myMap))
        for k := range myMap {
            keys = append(keys, k)
        }
    
        return keys
    }
    

    Or use maps.Keys.

    Also, from the design document:

    Why not use the syntax F<T> like C++ and Java?

    When parsing code within a function, such as v := F<T>, at the point of seeing the < it's ambiguous whether we are seeing a type instantiation or an expression using the < operator. Resolving that requires effectively unbounded lookahead. In general we strive to keep the Go parser simple.