Skip to main content
eLearner.app
Module 6 · Lesson 1 of 526/50 in the course~12 min
Module lessons (1/5)

Interfaces: defining a behavior

An interface in Go is a set of method signatures. A value implements the interface if it has all those methods — no implements, no extends, no explicit registration. It's the model often called "structural typing" or "static duck typing": the compiler checks conformance at compile time, but based on shape, not on declarations.

Declaring an interface

Go
type Greeter interface {
    Greet() string
}

Convention: names ending in -er for single-method interfaces (Reader, Writer, Stringer, Closer). Small interfaces (1–2 methods) are idiomatic: the standard library is full of tiny interfaces that compose together (io.ReadWriter, io.ReadCloser, …).

Implicit implementation

Go
type Person struct{ Name string }

func (p Person) Greet() string {
    return "ciao " + p.Name
}

// Person satisfies Greeter because it has the required method.
var s Greeter = Person{Name: "Ada"}
fmt.Println(s.Greet())

No keyword. If the type has the methods, it can be assigned to a variable of that interface type. That's it.

Polymorphism via interface

Go
type Robot struct{ ID string }
func (r Robot) Greet() string { return "bip " + r.ID }

func greet(s Greeter) {
    fmt.Println(s.Greet())
}

greet(Person{Name: "Ada"})
greet(Robot{ID: "R2"})

greet accepts any type that satisfies Greeter. This is the Go way of doing polymorphism: no hierarchies, just capability.

The empty interface

Go
var x interface{} = 42
var y any = "ciao"   // any is the built-in alias of interface{}

interface{} (or any since Go 1.18) requires no methods, so any value satisfies it. Useful for generic containers, but to extract the concrete value you need a type assertion or type switch (next lessons).

Method set: value vs pointer receiver (preview)

Recall from Module 5:

  • Methods with a value receiver are in the method set of both T and *T.
  • Methods with a pointer receiver are ONLY in the method set of *T.

Practical consequence:

Go
type Counter struct{ N int }
func (c *Counter) Inc() { c.N++ }

type Incrementer interface { Inc() }

var i Incrementer = &Counter{}   // OK: *Counter has Inc()
// var j Incrementer = Counter{} // ERROR: Counter (value) does NOT

When a method has a pointer receiver, you must assign a pointer to the interface variable.

Try it

Exercise#go.m6.l1.e1
Attempts: 0Loading…

Define an interface Greeter with a single method Greet() string.

Loading editor…
Show hint

Syntax: `type Name interface { Method(args) return }`.

Solution available after 3 attempts

Exercise#go.m6.l1.e2
Attempts: 0Loading…

Implement Greeter on a new type Robot with field ID string; the method returns 'bip ' + ID.

Loading editor…
Show hint

No `implements`: just define the method with the right signature.

Solution available after 3 attempts

Quiz#go.m6.l1.e3
Ready

How do you declare that type P implements the Greeter interface?

Go
type P struct{}
// ?
Answer options

Recap

  • Interface = set of method signatures; no implements.
  • Implicit implementation: just have the methods with the right signature.
  • Idiomatic: small interfaces (1–2 methods), names in -er.
  • interface{} / any: accepts any value, loses type safety.
  • Method set: pointer receiver → only *T satisfies the interface.
  • Go polymorphism: interface-typed parameters, no hierarchies.