Go generic methods is here

2026-05-28
golangprogramming

Generic methods merged in Go

The Go team has merged generic methods. A concrete method can now declare its own type parameters, not just borrow them from a generic receiver. It's implemented and documented. The only thing left is removing the flag that gates it, which the team is keeping around for a bit so they can rule out generic methods as the cause of any bug during the release process.

I've wanted this for a while, and not for anything exotic. I just got tired of moving things off a type and into package-level functions whenever they needed a type parameter. If Set has an add operation that's generic over the element type, I want to write s.Add(x), not containers.Add(s, x) and then go remember which package I hid Add in. And I can't autocomplete my way to it if I don't remember the package. So this gives us a pretty nifty ergonomics improvement.

But as with all deals with the devil, there's something you have to sacrifice. And here, it's the fact that a generic method can't participate in interface satisfaction.

Why the restriction is there

It's about how the call gets dispatched (how Go resolves an interface call at runtime). In C# you say explicitly that a type implements an interface:

interface IBox {
    T Get<T>();
}
class Box : IBox {
    public T Get<T>() => ...;
}

Go doesn't work that way (bro's not that guy). You never declare intent, because Go is all about implicit interface satisfaction. The compiler checks structurally that a type's method set covers the interface, and it does that check when you assign a concrete value to an interface variable:

type Getter interface {
    Get() any
}

type Box struct{}
func (*Box) Get() any { ... }

var g Getter = &Box{}   // checked here

That's fine for an ordinary method, because the method set is fixed and finite. A generic method isn't. It's a family of methods, one per type argument:

func (*Box) Get[T any]() T { ... }

Since nothing declares interface intent up front, the compiler can't know which instantiations of Get will ever be needed, so there's no finite set to build a dispatch table from. The Go team has said for years they don't know how to implement this without imposing a cost on code that doesn't use it. So the generic Get does not satisfy Getter:

var g Getter = &Box{}   // compile error once Get is generic

The way the proposal gets around it is to stop treating a method as primarily a way to implement an interface. A method is just a function attached to a type. It's useful for namespacing and for reading x.a().b().c() left to right, interface or no interface.

What it costs

If you're looking for the tl;dr of how this impacts your Go codebase, fret not. There are no runtime costs, no bloated binaries, no memory hit. They went around the problem instead of paying for it, which is why this landed without much fuss. If there were real impact, it'd have been a lot more contentious.

The cost is conceptual (and philosophical?). Implicit interface satisfaction still works exactly as before. What changed is that "any method can participate in satisfying an interface" stopped being true. Generic methods are the first kind of method you can write that's flat-out barred from interface satisfaction. People have raised this as an orthogonality break from the philosophy of Go in general, and some aren't convinced the usage examples so far justify it.