Skip to content

Day 033 — strings, strconv & bytes

Month 2 · Week 1 · ⬅ Day 032 · Day 034 ➡ · Journal index

🎯 Learning Objective

Wield the three text-wrangling workhorses: strings for search/split/replace, strconv for explicit string↔number conversion, and bytes as the mutable []byte mirror of strings.

📚 Topics

  • strings: Split, Fields, Cut, Contains, Replace*, Trim*, Index
  • strconv: Atoi/Itoa, ParseInt/ParseFloat/ParseBool, Format*, Quote
  • bytes: Buffer, Index, mirror of strings for []byte
  • The conversion-vs-cast distinction (strconvstring(int))

📖 Reading / Sources

📝 Notes

  • strings.Split(s, sep) splits on every sep; strings.Fields(s) splits on runs of whitespace (no empty tokens) — use Fields for "split on spaces" → [[strings-split]].
  • strings.Cut(s, sep) (Go 1.18+) returns before, after, found around the first sep — the clean idiom for key=value parsing, replacing Index+slicing.
  • Search/test helpers: Contains, HasPrefix, HasSuffix, Index, Count. Transformers: ReplaceAll, ToLower/ToUpper, TrimSpace, Trim/TrimLeft/TrimRight, Repeat, Join.
  • strconv is conversion, not casting. string(65) produces "A" (the rune), not "65" — a classic bug. To turn the number 65 into "65", use strconv.Itoa(65) → [[strconv-vs-cast]].
  • strconv.Atoi/Itoa are the int↔string shortcuts. For control over base and bit size, use ParseInt(s, base, bitSize) / FormatInt(i, base), plus ParseFloat/ParseBool. They always return an error — never discard it; bad input is *strconv.NumError.
  • strconv.Quote(s) adds quotes and escapes (the engine behind %q); Unquote reverses it.
  • bytes mirrors strings but operates on []byte, avoiding string([]byte) allocations when you already hold bytes (e.g. from a network read). bytes.IndexByte, bytes.Split, bytes.Contains, etc.
  • bytes.Buffer is a growable, read+write byte container that satisfies both io.Reader and io.Writer — ideal when an API needs both, or for assembling output you'll later consume.

💻 Code Examples

i, err := strconv.Atoi("42")          // 42, nil  — NOT string casting
_, err2 := strconv.Atoi("4x2")        // 0, *strconv.NumError
hex, _ := strconv.ParseInt("ff", 16, 64) // 255 (base 16)
before, after, found := strings.Cut("key=value", "=") // "key","value",true
_ = i; _ = err; _ = err2; _ = hex; _ = before; _ = after; _ = found

Full code: examples/month-02/strings-strconv/main.go · Run: go run ./examples/month-02/strings-strconv

🏋️ Exercises / Practice

Exercise Status Link
Sum CSV integer columns (Split + strconv + %w) exercises/month-02/week-1/csvsum

🐛 Mistakes Made

  • Wrote string(42) expecting "42" and got "*" (rune U+002A). Switched to strconv.Itoa.
  • Ignored the error from strconv.Atoi on user input and propagated a silent 0.

❓ Open Questions

  • When does converting []bytestring actually allocate, and when does the compiler optimize it away (e.g. map lookups)?

🧠 Active Recall (answer without looking)

  1. Q: What is the result and type of string(65), and how do you get "65"?

    A `string(65)` is `"A"` — it interprets 65 as a rune (U+0041). To render the digits `"65"`, use `strconv.Itoa(65)`.

  2. Q: You want to split a sentence into words, ignoring extra spaces. Split or Fields?

    A `strings.Fields` — it splits on runs of whitespace and drops empty tokens. `strings.Split(s, " ")` would emit empty strings for consecutive spaces.

🪶 Feynman Reflection

strings and bytes are twins: same toolbox, one for immutable text and one for mutable byte buffers. strconv is the careful translator between text and numbers — and it's careful on purpose, returning an error every time, because "abc" is not a number and Go won't pretend it is. The trap is thinking a type conversion string(n) does that translation; it doesn't — it picks a rune.

🕳️ Knowledge Gaps

  • strings.Replacer for multi-pair replacement; unicode package case folding.

✅ Summary

I can search/split/replace text, convert between strings and numbers safely with strconv, and use bytes/bytes.Buffer to avoid needless allocations.

⏭️ Next Steps / Prep for Tomorrow

  • Day 034: strings.Builder and why += in a loop is a performance trap.

Time spent Difficulty Confidence
90 min 🟦🟦⬜⬜⬜ 🟦🟦🟦⬜⬜

Suggested commit: feat(examples): strings, strconv, and bytes packages (day 033)