How to use
- Copy the installation command and review the source package before installing it in your own agent environment.
- Check the source document for required tools, credentials and supported hosts.
- Describe your input and desired deliverable; review the output against the source material.
npx skills add https://github.com/fabianoflorentino/golang-agent-skills --skill golang-pitfalls-stringsBefore you start
- Installation does not include a model subscription, API allowance or permission to access your files.
- Repository stars and installation counts describe activity, not an independent quality or security test.
Rendered from the source repository. Headings, examples, code, tables, links, and referenced images are preserved.
Golang Pitfalls: Strings & Bytes
Source material: mistakes #36-41 from 100 Go Mistakes and How to Avoid Them (teivah/100-go-mistakes).
Apply these rules when manipulating strings in Go.
36. Not understanding the concept of rune (#36)
- A charset is a set of characters; an encoding translates characters to binary.
- A Go string references an immutable slice of arbitrary bytes. Source-code literals are UTF-8, but strings from elsewhere may not be.
- A
runeis a Unicode code point, encoded in UTF-8 using 1 to 4 bytes. - `len(s)` returns the number of bytes, not runes. (
"hêllo"has 5 runes butlen== 6.)
37. Inaccurate string iteration (#37)
for i := range siterates over the starting byte index of each rune, not each rune.s[i]returns a single byte — printing it corrupts multi-byte runes (e.g.,êprints asÃ).- To print all runes, use the value element:
for i, r := range s { ... }. - To access the ith rune, convert to
[]rune:[]rune(s)[i]. This conversion costs O(n) — avoid it in hot loops; preferrangewith the value when iterating everything.
38. Misusing trim functions (#38)
strings.TrimRight(s, cutset)/strings.TrimLeftremove all trailing/leading runes contained in the cutset.strings.TrimRight("123oxo", "xo")→"123".strings.TrimSuffix(s, suffix)/strings.TrimPrefix(s, prefix)remove only the exact provided suffix/prefix (a single occurrence).- Pick the right function for the intent.
39. Under-optimized string concatenation (#39)
- Strings are immutable;
s += valuein a loop reallocates a new string every iteration — slow. - Use
strings.Builder:
sb := strings.Builder{}
for _, value := range values {
sb.WriteString(value)
}
return sb.String()- Preallocate with
sb.Grow(totalLen)when total length is known — ~78% faster than without, ~99% faster than+=in benchmarks. strings.Builderis not safe for concurrent use. For concatenating just a few strings,+=orfmt.Sprintfis clearer and fine.
40. Useless string conversions (#40)
- Most I/O works with
[]byte(io.Reader,io.Writer,io.ReadAll), not strings. - The
bytespackage matches everystringsoperation (Split,Count,Contains,Index, ...). - Consider implementing the whole workflow with
[]byteto avoid repeated string↔byte conversions.
41. Substring and memory leaks (#41)
- A substring shares the backing array with the original string — keeping the substring keeps the whole string alive.
- Substring indexes are byte-based, not rune-based.
- To release memory, copy the substring manually or use
strings.Clone(Go 1.18+).
Cross-References
- → See
fabianoflorentino/golang-agent-skills@golang-performancefor allocation-aware string building - → See
fabianoflorentino/golang-agent-skills@golang-safetyfor nil and boundary mishandling in string processing



