Skip to content

Weekly Review — Month 1 · Week 3 (Days 015–021)

Journal index · Roadmap › Week 3

📅 The Week in One Line

Gave types behavior with methods, decoupled code with implicitly-satisfied interfaces, and learned the full Go error toolkit — wrapping, sentinel/custom errors, Is/As/Join, and panic/recover.

✅ What I Completed

  • Day 015 — Methods & receivers (value vs pointer)
  • Day 016 — Interfaces & implicit satisfaction
  • Day 017 — Type assertions & type switches
  • Day 018 — Errors as values & wrapping (%w)
  • Day 019 — Custom & sentinel errors; errors.Is/As/Join
  • Day 020 — panic, recover & when to use them
  • Day 021 — Review & closed-book recall
  • Runnable examples: methods, interfaces, errors, panic-recover
  • Exercises solved: 3 (shapes, counter, validate) — all with table-driven tests

💡 Lessons Learned

  • Value vs pointer receiver is one rule: value = copy (read-only), pointer = original (mutates). Keep a type's receivers consistent.
  • Interface satisfaction is implicit and based on method sets, which is why a T value can fail to satisfy an interface implemented on *T.
  • The nil-interface trap is real: a typed nil pointer stored in an error is non-nil. Return literal nil for success.
  • %w keeps the error chain inspectable; %v flattens and breaks it. Compare with errors.Is, never ==, once wrapping is involved.
  • errors.As extracts typed errors; errors.Join (Go 1.20+) bundles many. Give custom error types an Unwrap() so the chain stays walkable.
  • Panic is for programmer bugs/invariants (MustCompile), not expected failures. recover only works inside a deferred function.

💪 Strengths (what clicked)

  • Methods and small interfaces ("accept interfaces, return structs") felt natural.
  • Building and reading error chains with %w + errors.Is/As.

🧩 Weaknesses (what's still fuzzy)

  • Reflex to reach for errors.Is/As instead of == under time pressure.
  • Spotting the nil-interface trap before it bites.
  • Addressability rules for auto-& on pointer-method calls.

🔁 Spaced-Repetition Re-quiz (topics from earlier weeks)

  1. Q: (Wk1) What does defer evaluate eagerly vs run lazily?
    AArguments are evaluated when the defer statement runs; the call executes LIFO at function return.
  2. Q: (Wk2) What happens to a slice's backing array when append exceeds cap?
    AA new, larger backing array is allocated and elements are copied; the old aliasing is broken. Within cap, append mutates the shared backing array.
  3. Q: (Wk3) errors.Is vs errors.As?
    AIs checks for a specific sentinel value anywhere in the chain; As finds and extracts an error of a given type so you can read its fields.
  4. Q: (Wk3) Why use a pointer receiver?
    ATo mutate the receiver, to avoid copying a large struct, or for consistency when other methods need a pointer.

🎯 Action Items

  • Add a flashcard pair: "== sentinel → use errors.Is" and "typed nil → nil-interface trap".
  • Re-implement the validate exercise from scratch using only errors.Join.
  • Skim io.Reader/io.Writer source to see small interfaces in the wild before Week 4.

🚀 Next Week Goals

  • Generics (type parameters, constraints) and deeper testing (subtests, fuzzing basics).
  • Apply this week's interfaces + errors in the first real mini-project boundary.

📊 Metrics

Hours Days hit Exercises Commits Avg confidence
9 7/7 3 7 3.⅗

Suggested commit: docs(journal): week 3 review