Middle · Go foundations

Generics, interfaces and typed code

When should a reusable function be generic?

Try explaining this aloud before opening the answer. State your assumptions and trace a boundary case.

EXAMPLE · FRAGMENT UNLESS A COMPLETE PROGRAM IS SHOWN

go
func Contains[T comparable](xs []T, target T) bool {
    for _, x := range xs {
        if x == target { return true }
    }
    return false
}
Reveal a strong answer
  1. Use a type parameter when an algorithm has the same type-safe implementation for several types and preserving that type matters, such as a collection transform. Use a behavior interface when implementations differ behind operations.

  2. Constraints define permitted operations. comparable allows equality but not ordering; ~int admits named types with underlying int. A type parameter does not supply arbitrary fields or dynamic methods.

  3. Prefer a concrete function when only one case exists. Evaluate readability and generated code with real tooling instead of assuming generics remove all runtime costs or always cause boxing.

Common trap

Replacing every interface with a type parameter often complicates APIs without preserving any useful relationship.

Complexity & use

O(n) comparisons; comparison cost depends on T.

Try it

Write a generic Contains function and explain why it cannot accept []map[string]int.

Worked solution

Contains[T comparable] can compare T with ==. Maps are not comparable except to nil; choose a key projection or equality function when semantic equality is needed.

Change the constraint

Explain which assumption would change your choice, and show a test that detects that change.

How did you do?

Self-assessment, not a compiler pass or interview score. Explain the reasoning unaided before marking understood.

Not marked. Progress stays on this browser, separate from course completion.

Primary references

Checked 2026-10-20. Use documentation for your pinned runtime, driver and tool version.