«X does not implement Y»: Understanding the Pointer Receiver Error in Go

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: A Moment of Truth for Go Developers

\n\n

If you've ever written code in Go (Golang) and used interfaces, you've likely encountered this compiler message:

\n\n
cannot use x (variable of type *MyStruct) as type MyInterface value in assignment:\n*MyStruct does not implement MyInterface (method GetName has a pointer receiver)
\n\n

On Stack Overflow, this question gathers thousands of views. Beginners get stuck, and experienced developers shrug. But behind this error lies an elegant and important concept: the difference between a value receiver and a pointer receiver in the Go language.

\n\n

In this article, we'll look under the hood of the Go compiler, analyze real code examples, and understand how to avoid this pitfall. You'll learn not only why the error occurs but also how it relates to the type and interface system.

\n\n

1. Interfaces in Go: A Quick Primer

\n\n

Before diving into the error, let's recall how Go interfaces work. Unlike Java or C++, an interface in Go is a set of methods. If a type implements all the methods of an interface, it automatically satisfies that interface (duck typing).

\n\n

Example of a simple interface:

\n\n
type Speaker interface {\n    Speak() string\n}
\n\n

Now let's define a struct and one method:

\n\n
type Dog struct {\n    Name string\n}\n\n// Value receiver — the method works with a copy of the struct\nfunc (d Dog) Speak() string {\n    return "Woof! I am " + d.Name\n}
\n\n

Here, Dog implements Speaker. It works with both Dog and *Dog:

\n\n
var s Speaker\ns = Dog{Name: "Buddy"}  // ✅ OK\ns = &Dog{Name: "Rex"}  // ✅ OK (Go automatically dereferences)
\n\n

So far, so simple. Now let's change the method to a pointer receiver:

\n\n
func (d *Dog) Speak() string {\n    return "Woof! I am " + d.Name\n}
\n\n

And here's where the magic begins.

\n\n

2. Pointer Receiver vs Value Receiver: What's the Difference?

\n\n

In Go, methods can have two types of receivers:

\n\n
    \n
  • Value receiver (t Type) — the method receives a copy of the value.
  • \n
  • Pointer receiver (t *Type) — the method receives a pointer to the original value.
  • \n
\n\n

Why is this important? Because the method set of a type depends on which receiver is used.

\n\n

Truth table:

\n\n
    \n
  • Type T has all methods with a value receiver (for T).
  • \n
  • Type *T has all methods with a value receiver + pointer receiver.
  • \n
\n\n

In other words: the pointer gets a "bonus" set of methods, while the value only gets those declared with a value receiver.

\n\n

This is not a bug but a feature of Go's design. The compiler cannot automatically take the address of a value if it is not addressable (e.g., a function result or a literal).

\n\n

3. Breaking Down the Error: «method has a pointer receiver»

\n\n

Let's go back to our example. If Speak() is declared with *Dog, then:

\n\n
var s Speaker\ns = Dog{Name: "Buddy"}  // ❌ ERROR\n// cannot use Dog{...} as Speaker...\n// method has a pointer receiver
\n\n

Why? Because Dog (not a pointer) does not have the Speak() method in its set. The method belongs only to *Dog.

\n\n

But this works:

\n\n
s = &Dog{Name: "Buddy"}  // ✅ OK
\n\n

Now let's look at a more practical example from real code, often seen on Stack Overflow.

\n\n

Example: Interface and Struct with Data

\n\n
package main\n\nimport "fmt"\n\ntype User interface {\n    GetID() int\n    SetName(name string)\n}\n\ntype Admin struct {\n    ID   int\                

Blogs

Book Recommendations