Is it possible in Go to have a function parameter of a type that satisfies multiple types? I know you can use interfaces to pass in various types, but let me give an example.
Say I have the following three types:
type thing struct {
name string
}
type barThing struct {
thing
barAttr string
}
type fooThing struct {
thing
fooAttr int
}
I'd like to have a single functions such that I can pass in a map[string]<anyOfThoseTypes>
and add each map item's key to the name field. Something like:
func copyKeysIntoStruct(m map[string]thing) {
for k, v := range m {
v.name = k
m[k] = v
}
}
func main() {
bars := map[string]barThing{
"b1": {thing: thing{name: "overwrite"}},
"b2": {thing: thing{}},
}
foos := map[string]fooThing{
"f1": {thing: thing{}},
"f2": {thing: thing{name: "goingaway"}},
}
bars = copyKeysIntoStruct(bars)
fmt.Println(bars)
foos = copyKeysIntoStruct(foos)
fmt.Println(foos)
}
However, here I get cannot use bars (type map[string]barThing) as type map[string]thing in argument to copyKeysIntoStruct
, which makes sense. However, I don't want to write this same function for each type that has thing
embedded.
The other possibility was to take m map[string]interface{}
as an argument and use a type switch and assertions to get the right behavior, but that seemed to be a NOGO too.
In summary, I'm looking to have inputs like:
bars := map[string]barThing{
"b1": {thing: thing{name: "overwrite"}},
"b2": {thing: thing{}},
}
foos := map[string]fooThing{
"f1": {thing: thing{}},
"f2": {thing: thing{name: "goingaway"}},
}
and outputs like:
bars := map[string]barThing{
"b1": {thing: thing{name: "b1"}},
"b2": {thing: thing{name: "b2"}},
}
foos := map[string]fooThing{
"f1": {thing: thing{name: "f1"}},
"f2": {thing: thing{name: "f2"}},
}