What's the difference between types.Implements and types.Satisfies in golang?
I'm working on a code that inspects Go AST.
What's the difference between types.Implements and types.Satisfies in golang?
I'm working on a code that inspects Go AST.
Copyright © 2021 Jogjafile Inc.
tl;dr
A type may "satisfy"
comparablewithout "implementing" it, i.e. without belonging to its type set.The method names are directly related to the language specification, so it helps to look at that first:
Implementing is defined as:
The concept of "type set" is also defined in the specs and depends on what kind of interface you are considering. Basic interfaces are those which include only methods, and the type set is the set of all types that implement those methods, e.g.:
Non-basic interfaces are those which include type terms (and zero or more methods), the type set is the set of the specified types. If any term is approximate, e.g.
~intthe set includes types that haveintas underlying type.Satisfying is used only for interface constraints and is defined as:
As you can see the definition of "satisfying" includes "implementing" plus an exception.
Before Go 1.20, the concept of "satisfying" an interface — any interface — didn't exist. Every use case was called "implementing".
In Go 1.20 "satisfying" was introduced to expand the definition of "implementing a constraint" with an exception (the second bullet point in the above quote) for types that had to satisfy
comparable. Before, types such asreflect.Typeor[2]io.Readerdidn't implementcomparabledespite supporting==and!=operators in non-generic code.In other words, there was a mismatch between the definition of comparable as per the spec, and the actual type set of the
comparableconstraint.More info: Go generics: type constraint for map keys?