compare Strings Package with an alternative
Fast recall
Quick revision
Core answer
Practical understanding of Strings Package.
Repeating a definition without saying when to use it.
Give one trade-off and say how you would test it.
Interview-ready guide
Interview answer
Replace's signature carries the count:
strings.Replace("a-b-c-d", "-", "+", 2) // a+b+c-d — first TWO only
strings.Replace("a-b-c-d", "-", "+", -1) // a+b+c+d — all
strings.ReplaceAll("a-b-c-d", "-", "+") // a+b+c+d — the -1 namedExecuted. The count is left-to-right — the 'first N' occurrences. -1 is the all-sentinel. ReplaceAll (Go 1.12) is Replace(s, o, n, -1) with a name — use it for the common case; keep Replace for partial replacement (the first occurrence only: n=1).
The return, always: a NEW string (immutable — of course). If old doesn't appear, the ORIGINAL string is returned — a free no-op, no allocation (the runtime checks before building).
The regex boundary: Replace handles LITERAL substrings. When the 'what to replace' is a pattern (all digits, word boundaries, case-insensitive) — that's regexp.ReplaceAllString, the heavier tool (compile once, reuse; ~10-50x slower than strings.Replace, per docs' own guidance).
The multibyte honesty: old and new are substrings matched in bytes — replacement of multibyte runes works exactly (the whole rune's bytes match), and the count counts OCCURRENCES of the whole old string, never partial byte overlaps.
compare Strings Package with an alternative
Direct Answer
strings.Replace(s, old, new, n): n is how many occurrences to replace (left-to-right); -1 replaces all. For all-replacements, Go 1.12+ has ReplaceAll (same as Replace with -1).
Deep Dive & Architecture
The implementation tiers behind Replace: for the no-match case, the original pointer returns (zero cost). For small counts, the scan-replace builds incrementally. The workhorse underneath is strings.genReplace — a single generalized implementation serving Replace, ReplaceAll, and (via a different entry) the Title/Builder paths — with the count threading through as the loop bound.
Why the count exists at all (API archaeology): pre-strings-function libraries (C's strncpy world, sed's g flag) made 'replace first N' a real operation — Go kept the explicit n because partial replacement is genuinely common: 'replace the first occurrence of the placeholder', 'escape the first quote.' The -1-all sentinel plus the later ReplaceAll naming is the API evolving toward the common case without breaking the general one — the same pattern as fmt's %v and %-specific verbs.
The regexp crossover deserves the numbers interviewers respect: strings.Replace is a substring search (Boyer-Moore-ish) with a straight build; regexp compiles the pattern (compile ONCE, outside the loop — the classic mistake is compiling per call), backtracks or automata-matches, and allocates captures. The docs' own performance note: for literal replacements, strings.Replace; for patterns, regexp — and 'literal' includes FIXED separators in untrusted input (a delimiter in a config format is literal even though the input varies). The wrong-tool bugs: regexp for literal work (10-50x slow, allocation-heavy) and Replace for pattern work (can't express 'all digits' at all).
Common Mistakes & Pitfalls
Repeating a definition without saying when to use it.
Check your understanding
Answer these without looking back at the article.
- What is Strings Package, and when would you use it?
- When would you use Strings Package in a real project?
- What is a common mistake when using Strings Package?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.