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)