Reputation: 15197
Take this sample of code (playground):
package main
import (
"fmt"
)
type Foo struct {
Name string
}
var data = make(map[string]interface{})
func main() {
data["foo"] = &Foo{"John"}
foo := data["foo"].(*Foo)
fmt.Println(foo.Name)
}
When I add something to data
, the type turns into an interface{}
, so when I later retrieve that value I have to assert the original type back onto it. Is there a way to, for example, define a getter function for data
which will automagically assert the type?
Upvotes: 0
Views: 1564
Reputation: 121442
You can do something like this, but you might want to think about your design.. It is very rare that you need to do this kind of things.
http://play.golang.org/p/qPSxRoozaM
package main
import (
"fmt"
)
type GenericMap map[string]interface{}
func (gm GenericMap) GetString(key string) string {
return gm[key].(string)
}
func (gm GenericMap) GetFoo(key string) *Foo {
return gm[key].(*Foo)
}
func (gm GenericMap) GetInt(key string) int {
return gm[key].(int)
}
var data = make(GenericMap)
type Foo struct {
Name string
}
func main() {
data["foo"] = &Foo{"John"}
foo := data.GetFoo("foo")
fmt.Println(foo.Name)
}
You might want to add error checking, in case the key does not exists or is not the expected type.
Upvotes: 2
Reputation: 1323223
Not really, unless you turn to reflect
and try to get the type of the interface that way.
But the idiomatic (and faster) way remains the type assertion (a "type conversion" which must be checked at runtime, since data
only contains interface{}
values).
If data were to reference a specific interface (instead of the generic interface{}
one), like I mentioned here, then you could use a Name()
method defined directly on it.
Upvotes: 3