Home > Blockchain >  Access struct fields through interface
Access struct fields through interface

Time:11-14

Regardless of whether is this an idiomatic go or not, in some situations we want to access an underlying concrete value of an interface value. here is an example:

I have these structs and interface:

type person struct {
    name string
    age  int
}

type secretAgent struct {
    name string
    age  int
}

type Human interface {
    speak()
}

func (p person) speak() {}
func (p secretAgent) speak() {}

And I also have this function:

func bar(h Human) {
    fmt.Println(h.name, "is sent to bar!!") // <-- name is not accessible 
}

p1 := person{"foo bar", 34}
bar(p1)

How can I access struct fields in this situation?

CodePudding user response:

An interface is just a collection of methods.

Add a method to retrieve the name to it:

type Human interface {
    speak()
    name() string
}

func (p person) speak() {}
func (p person) name() string { return p.name }

func (p secretAgent) speak() {}
func (p secretAgent) name() string { return p.name }

func bar(h Human) {
    fmt.Println(h.name(), "is sent to bar!!") // <-- name is now accessible 
}

CodePudding user response:

For any one who might be interesting it this question, I found the solution.

Regardless of whether is this an idiomatic go or not, because interface can't find the exact type you are trying to access through it, you should assert the type of interface value.

A type assertion provides access to an interface value's underlying concrete value.

so in my case the implementation would be like this:

func bar(h Human) {
    switch h := h.(type) { // <-- this is type assertion
    case person:
        fmt.Println(h.name, "is sent to bar!!") // <-- just has access to person
    case secretAgent:
        fmt.Println(h.name, "is sent to bar!!") // <-- has access to secretAgent
    }
}
  •  Tags:  
  • go
  • Related