DEV Community

Shams Pathan
Shams Pathan

Posted on Originally published at shamspathan.Medium

Why You Can’t Access Struct Fields Through Interfaces in Go (and How to Fix It)

Ever written something like this in Go?

var a Animal = Dog{Name: "Charlie"}
fmt.Println(a.Name) // 💥 compile-time error
Enter fullscreen mode Exit fullscreen mode

...and thought, “Wait — why can’t I access Name when it’s clearly part of the struct?”


🔍 Why This Happens

In Go, interfaces are contracts, not containers for struct fields. They only guarantee access to methods, not fields. So when you assign a struct to an interface, Go stores it as a hidden value — only accessible if you:

  • Know the underlying type
  • Use type assertion, or
  • Use reflection

🧪 Real-World Example: API Payload

Let’s say you’re writing an API handler that receives some payload:

type User struct {
    Name  string
    Email string
}

func (u User) IsValid() bool {
    return u.Email != ""
}

type Payload interface {
    IsValid() bool
}
Enter fullscreen mode Exit fullscreen mode

Now in your handler:

func Handle(p Payload) {
    fmt.Println(p.IsValid()) // ✅ fine
    fmt.Println(p.Name)      // ❌ compile error
}
Enter fullscreen mode Exit fullscreen mode

Yep — Go won’t let you access p.Name. Because Payload doesn’t know Name exists.


✅ Solution: Type Assertion

You can safely access the struct’s fields if you assert its type:

if u, ok := p.(User); ok {
    fmt.Println(u.Name) // 🎯 works!
}
Enter fullscreen mode Exit fullscreen mode

Or if you’re not sure of the type, use a type switch:

switch v := p.(type) {
case User:
    fmt.Println(v.Name)
default:
    fmt.Println("Unknown type")
}
Enter fullscreen mode Exit fullscreen mode

⚠️ Or... Use Reflection (Carefully)

You can also access struct fields dynamically via reflect, like:

val := reflect.ValueOf(p)
field := val.FieldByName("Name")
fmt.Println(field.String())
Enter fullscreen mode Exit fullscreen mode

But reflection can be tricky and error-prone. Use it only when you can’t use static typing — like dynamic JSON decoding or generic form handlers.


✨ Conclusion

Go’s strict typing can feel limiting at first, but it protects you from a whole class of bugs. Once you understand interfaces don’t “carry” struct fields — just methods — it all starts to click.

Want to go deeper? I shared the full breakdown with code samples and reflection examples here:

👉 Read the full post on Medium


Have you ever hit this issue in a real project? How did you work around it? Let’s chat below 👇

go #programming #backend #interfaces #reflection

Top comments (0)