Go Programming Fundamentals · Concurrency & Idiomatic Go

Error Handling and Interfaces

Write idiomatic, composable Go code

Error Handling and Interfaces

Go treats errors as ordinary values rather than exceptions. Functions typically return an error as the last value, and callers check it immediately.

result, err := divide(10, 0)
if err != nil {
    log.Println("failed:", err)
    return
}

Interfaces

An interface defines a set of method signatures. Any type that implements those methods automatically satisfies the interface, with no explicit declaration required.

type Shape interface {
    Area() float64
}

This structural typing makes it easy to write small, composable interfaces (like io.Reader and io.Writer) that many types can satisfy.

Practice questions

Why does Go encourage checking `err != nil` immediately after every call that can fail?

Answer

Summary

Because errors are just values, not automatically propagated exceptions — if you don't check immediately, a nil/zero result from a failed call can silently flow further into your program and cause confusing bugs downstream.

Longer Answer

Because errors are just values, not automatically propagated exceptions — if you don't check immediately, a nil/zero result from a failed call can silently flow further into your program and cause confusing bugs downstream. This is a direct consequence of errors being ordinary values in Go — nothing forces you to handle them except your own discipline (or a linter). In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview.

Key Points

  • Because errors are just values, not automatically propagated exceptions — if you don't check immediately, a nil/zero result from a failed call can silently flow further into your program and cause confusing bugs downstream
  • This is a direct consequence of errors being ordinary values in Go — nothing forces you to handle them except your own discipline (or a linter)
  • In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview
  • Use the answer to connect the concept back to a realistic production or interview scenario for 'Why does Go encourage checking err != nil immediately after every call that can fail?'

Comparison / Tradeoffs

Aspect Notes
Core idea Because errors are just values, not automatically propagated exceptions — if you don't check immediately, a nil/zero result from a failed call can silently flow further into your program and cause confusing bugs downstream.
Practical tradeoff This is a direct consequence of errors being ordinary values in Go — nothing forces you to handle them except your own discipline (or a linter).

Why

Summary

This is a direct consequence of errors being ordinary values in Go — nothing forces you to handle them except your own discipline (or a linter).

Longer Answer

This is a direct consequence of errors being ordinary values in Go — nothing forces you to handle them except your own discipline (or a linter). In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview.

Key Points

  • This is a direct consequence of errors being ordinary values in Go — nothing forces you to handle them except your own discipline (or a linter)
  • In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview
  • In an interview, relate 'Why does Go encourage checking err != nil immediately after every call that can fail?' to implementation decisions, tradeoffs, and operational impact
  • Use the answer to connect the concept back to a realistic production or interview scenario for 'Why does Go encourage checking err != nil immediately after every call that can fail?'

Comparison / Tradeoffs

Aspect Notes
Core idea This is a direct consequence of errors being ordinary values in Go — nothing forces you to handle them except your own discipline (or a linter).
Practical tradeoff In an interview, relate 'Why does Go encourage checking err != nil immediately after every call that can fail?' to implementation decisions, tradeoffs, and operational impact.
What's the practical benefit of Go's structural interfaces like `io.Reader` and `io.Writer` being so small?

Answer

Summary

A tiny interface (often just one method) is easy for any type to satisfy, so it ends up usable in far more places — a small Read([]byte) (int, error) method can come from a file, a network connection, or an in-memory buffer, and all work interchangeably wherever an io.Reader is expected.

Longer Answer

A tiny interface (often just one method) is easy for any type to satisfy, so it ends up usable in far more places — a small Read([]byte) (int, error) method can come from a file, a network connection, or an in-memory buffer, and all work interchangeably wherever an io.Reader is expected. This is the practical payoff of structural typing — minimal interfaces plus implicit satisfaction means broad interoperability with almost no ceremony. In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview.

Key Points

  • A tiny interface (often just one method) is easy for any type to satisfy, so it ends up usable in far more places — a small Read([]byte) (int, error) method can come from a file, a network connection, or an in-memory buffer, and all work interchangeably wherever an io.Reader is expected
  • This is the practical payoff of structural typing — minimal interfaces plus implicit satisfaction means broad interoperability with almost no ceremony
  • In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview
  • Use the answer to connect the concept back to a realistic production or interview scenario for 'What's the practical benefit of Go's structural interfaces like io.Reader and io.Writer being so small?'

Comparison / Tradeoffs

Aspect Notes
Core idea A tiny interface (often just one method) is easy for any type to satisfy, so it ends up usable in far more places — a small Read([]byte) (int, error) method can come from a file, a network connection, or an in-memory buffer, and all work interchangeably wherever an io.Reader is expected.
Practical tradeoff This is the practical payoff of structural typing — minimal interfaces plus implicit satisfaction means broad interoperability with almost no ceremony.

Why

Summary

This is the practical payoff of structural typing — minimal interfaces plus implicit satisfaction means broad interoperability with almost no ceremony.

Longer Answer

This is the practical payoff of structural typing — minimal interfaces plus implicit satisfaction means broad interoperability with almost no ceremony. In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview.

Key Points

  • This is the practical payoff of structural typing — minimal interfaces plus implicit satisfaction means broad interoperability with almost no ceremony
  • In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview
  • In an interview, relate 'What's the practical benefit of Go's structural interfaces like io.Reader and io.Writer being so small?' to implementation decisions, tradeoffs, and operational impact
  • Use the answer to connect the concept back to a realistic production or interview scenario for 'What's the practical benefit of Go's structural interfaces like io.Reader and io.Writer being so small?'

Comparison / Tradeoffs

Aspect Notes
Core idea This is the practical payoff of structural typing — minimal interfaces plus implicit satisfaction means broad interoperability with almost no ceremony.
Practical tradeoff In an interview, relate 'What's the practical benefit of Go's structural interfaces like io.Reader and io.Writer being so small?' to implementation decisions, tradeoffs, and operational impact.

Open in the app to mark lessons complete, take notes and track your progress.