fabianoflorentino/golang-agent-skills

golang-pitfalls-strings

Golang strings and bytes — the rune concept, len(s) returning bytes not runes, inaccurate string iteration over rune start indices, misusing trim functions, under-optimized string concatenation with strings.Builder, useless string to byte conversions, and s…

ソースを見る
リポジトリの原文

見出し、例、コード、表、リンク、参照画像を含む原文を表示しています。

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 rune is 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 but len == 6.)

37. Inaccurate string iteration (#37)

  • for i := range s iterates 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; prefer range with the value when iterating everything.

38. Misusing trim functions (#38)

  • strings.TrimRight(s, cutset) / strings.TrimLeft remove 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 += value in a loop reallocates a new string every iteration — slow.
  • Use strings.Builder:
go
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.Builder is not safe for concurrent use. For concatenating just a few strings, += or fmt.Sprintf is clearer and fine.

40. Useless string conversions (#40)

  • Most I/O works with []byte (io.Reader, io.Writer, io.ReadAll), not strings.
  • The bytes package matches every strings operation (Split, Count, Contains, Index, ...).
  • Consider implementing the whole workflow with []byte to 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-performance for allocation-aware string building
  • → See fabianoflorentino/golang-agent-skills@golang-safety for nil and boundary mishandling in string processing
同じリポジトリから

関連する Skills

すべての Skills
fabianoflorentino
コミュニティ

golang-design-patterns

Idiomatic Golang design patterns — functional options, constructor APIs, init() and global-state avoidance, enums, panic vs error decisions, resource management and lifecycle, graceful shutdown, timeouts and retries, streaming and iterators, and architecture styles (clean, hexagonal, DDD, flat). Apply when choosing between architectural patterns, implementing functional options, designing constructor APIs, setting up graceful shutdown, applying resilience patterns, or asking which idiomatic Go pattern fits a specific problem. Not for wiring a DI container or comparing DI libraries (→ See fabianoflorentino/golang-agent-skills@golang-dependency-injection skill), nor for error wrapping, errors.Is/As, or logging mechanics (→ See fabianoflorentino/golang-agent-skills@golang-error-handling skill).

導入数
1
GitHub Stars
0
更新日
9月14日
fabianoflorentino
コミュニティ

golang-google-wire

Compile-time dependency injection in Golang using google/wire — wire.NewSet, wire.Build, wire.Bind (interface→concrete), wire.Struct, wire.Value, wire.InterfaceValue, wire.FieldsOf, cleanup functions, //go:build wireinject injector files, and generated wiregen.go. Apply when using or adopting google/wire, when the codebase imports github.com/google/wire, or when wiring an application graph at compile time via wire.Build. For runtime DI with reflection, see fabianoflorentino/golang-agent-skills@golang-uber-dig skill.

導入数
1
GitHub Stars
0
更新日
9月14日
fabianoflorentino
コミュニティ

golang-lint

Linting best practices and golangci-lint configuration for Golang projects — running linters, configuring .golangci.yml, suppressing warnings with nolint directives, interpreting lint output, and selecting linters. Use when configuring golangci-lint, asking about lint warnings or nolint suppressions, setting up code quality tooling, or choosing linters. Also use when the user mentions golangci-lint, go vet, staticcheck, or revive. Not for wiring a lint step into a GitHub Actions pipeline (→ See fabianoflorentino/golang-agent-skills@golang-continuous-integration skill).

導入数
1
GitHub Stars
0
更新日
9月14日
fabianoflorentino
コミュニティ

golang-modernize

Modernize Golang code to use recent language features, standard library improvements, and idiomatic patterns. Use when reviewing Go code with old-style patterns, when encountering a deprecation warning, or when the user asks for modernization, a Go version upgrade (e.g. to Go 1.27), or a CI/tooling refresh. Not for structural refactors, extracting functions, or moving code between packages (→ See fabianoflorentino/golang-agent-skills@golang-refactoring skill).

導入数
1
GitHub Stars
0
更新日
9月14日