A struct groups named fields into a value. Assigning an Entry copies its fields; copying a pointer to an Entry shares one record. That distinction remains even though Go manages memory lifetime. Garbage collection does not make copies independent, and it does not decide which operations your API should allow to mutate a caller's object.
Methods add behavior to a named type. A value receiver receives a copy; a pointer receiver can update the referenced record. Choose the receiver from the method's semantics. The build's Add changes Hits and needs *Entry. Label only reads the record and can use Entry. Go can automatically take the address of an addressable value for a method call, but interface satisfaction still depends on the actual method set of the assigned value.
An interface belongs at the consuming boundary
An interface describes required methods, and a type satisfies it implicitly.
There is no implements declaration and no requirement to inherit from a base
class. A consumer needing only a label can accept interface { Label() string }
through a named Labeled interface. This is a behavior contract; it does not
promise that every implementation stores a Name field.
package main
import "fmt"
type Entry struct { Name string; Hits int }
func (e *Entry) Add(n int) { e.Hits += n }
func (e Entry) Label() string { return fmt.Sprintf("%s:%d", e.Name, e.Hits) }
type Labeled interface { Label() string }
func main() {
a := Entry{Name: "api", Hits: 1}
b := a
b.Add(2)
var item Labeled = a
fmt.Println(item.Label(), b.Label())
}The output is api:1 api:3. The record copy separated the numeric field, while
the interface lets the consumer call the promised method. Because Label has a
value receiver, both Entry and *Entry supply it. A method declared only on
*Entry would not be present in Entry's method set.
Keep the interface small and the nil policy explicit
Do not assert every Labeled value back to Entry just to recover its fields. That rejects unrelated valid implementations and duplicates their behavior. Call Label and preserve the input order. The tests include another type with the same method precisely to exercise this substitution.
An interface can contain a dynamic type and a nil pointer of that type; such an interface is not equal to nil. Calling a method may then panic if its receiver does not handle nil. The build excludes nil receivers explicitly, so you do not need to invent recovery behavior. The conceptual checks still ask you to recognize this distinction before using interface nil checks in a real API.
Use the fill to collect behavior through the interface, then repair one receiver bug and one ordering bug. Verify Add with zero and negative deltas and compare the original record with a modified copy.