Skip to content

Step 1 of 5 · Reading · ~4 min

Learn

Interfaces and Errors

Interfaces

By the end of this lesson you can hold values of different types in one slice, get a specific type back out when you need it, and control how a type prints and sorts. In Go Fundamentals error was a one-method interface; this is the general rule.

A method set is the contract

An interface is a list of method signatures. A type satisfies it by having those methods, with no implements keyword.

go

One slice holds two concrete types and the loop never asks which is which. The check is at compile time: assigning a Pallet with no Fee method to a Parcel fails with Pallet does not implement Parcel (missing Fee method).

What an interface value holds

A Parcel variable stores a pair: the dynamic type and the dynamic value it holds. %T prints the type:

go

The interface is nil only when both halves are empty, which is where Go's best-known trap lives:

go

*Box also satisfies Parcel, so this compiles, but the pair (*Box, nil) is not the empty pair. When you mean "nothing", return nil from a function declared to return Parcel.

Getting the concrete type back

go

Inside each case, v has that case's concrete type. The empty interface interface{} (the grader's Go has no any) accepts every type; only a switch or assertion lets you use what it holds.

Stringer and sort.Interface

fmt.Stringer is String() string. Println and %v call it when it exists:

go

Box has no String, so it falls back to {3}. Never format the receiver itself with %v inside its own String: it calls String again and recurses until the stack overflows. Print fields.

sort.Sort orders anything that implements Len() int, Less(i, j int) bool and Swap(i, j int). Give the slice a named type to hang them on:

go

sort.Sort(rack) alone does not compile: []Parcel has no Len, so convert with byFee(rack). It shares elements, so rack itself ends up sorted.

Design rules

Keep interfaces to one or two methods and define them where they are used. Accept an interface, return a concrete type. Pointer receivers change which types satisfy an interface; a later lesson covers that, and this one uses value receivers only.

Common mistakes

  • Using sort.Sort when ties matter. It does not promise to keep equal elements in input order, and for bigger slices they come out shuffled. sort.Stable(byFee(rack)) takes the same type and keeps input order.
  • Comparing on one key. A Less that looks only at the fee leaves equal fees in arbitrary order; a tie needs a second key. And > sorts largest first.
  • A missing String method. The value prints as {3} instead of the text you wrote.
  • Counting with a nil check. p == nil does not say which type a non-nil interface holds; use a type switch.

Your exercise

Build a registry that mixes three shape types in one sorted []Shape, prints each through String, and counts the types with a type switch. The starter reads and splits the input; the likeliest mistake is leaving ties in unspecified order.

Up nextErrors: Sentinels, Wrapping, Custom TypesInterfaces and Errors

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…