daryl
daryl

Reputation: 15197

Automatic Type Assertion In Go

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

Answers (2)

creack
creack

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

VonC
VonC

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

Related Questions