The 14‑Year Tug‑of‑War Over Go’s string(int) Conversion Reignited
After 14 years of dormancy, Go’s proposal #3939 to remove the confusing string(int) conversion—originally added for early formatting—has been moved to the regular proposal committee, prompting analysis of its semantics, historical reasons, compatibility concerns, and possible future outcomes.
Background
In August 2012 Rob Pike opened GitHub issue #3939 proposing to delete the string(int) conversion from Go. The conversion was originally added as a temporary aid for early formatting support and persisted for over a decade.
What string(int) Does
When the code
n := 65
s := string(n)
fmt.Println(s) // prints: Aexecutes, the Go specification defines the conversion as treating the integer as a Unicode code point and returning its UTF‑8 encoded character. Therefore string(65) yields the single‑character string "A", not the decimal representation "65".
The correct way to obtain a decimal string is:
n := 65
s := strconv.Itoa(n)
fmt.Println(s) // prints: 65Reasons for Removal (Rob Pike’s Proposal)
Historical artifact: the conversion was only needed to guide early formatting and is no longer required.
Unicode surrogate handling: converting values in the surrogate range U+D800–U+DFFF yields the Unicode replacement character \uFFFD. This creates an inconsistency because a literal string containing an illegal code point is a compile‑time error, while the runtime conversion silently produces \uFFFD.
Compatibility Constraint and “Soft Deletion”
Go’s Go 1 compatibility promise guarantees that code that compiles with Go 1 must continue to compile with future versions. Because string(int) is covered by this promise, the team avoided a hard removal.
Go 1.15 introduced a go vet check named stringintconv. When the pattern appears, go vet emits a warning such as:
conversion from int to string yields a string of one rune,
not a string of digits (did you mean fmt.Sprint(x)?)Open‑source projects including the AWS SDK and Prometheus received this warning after upgrading to Go 1.15 and performed bulk fixes.
Recent Proposal Activity
The Language Change Review Meeting recorded in issue #33892 contains a note from core team member Robert Griesemer:
#3939 moved to regular proposal committee for reconsideration
This moves the long‑idle issue from the review backlog to the regular proposal committee, triggering substantive re‑evaluation.
Possible Future Paths
Complete removal : Disallow string(int) entirely, causing a compilation error. This would directly conflict with the Go 1 compatibility guarantee.
Restrict to explicit rune conversion : Require developers to write string(rune(n)), making the intent of converting a code point explicit while preserving the existing semantics.
Maintain status quo : Keep the go vet warning and leave the language unchanged.
Any change would likely involve a multi‑release migration period and tooling support, as demonstrated by previous compatibility‑sensitive changes.
Practical Guidance
While the syntax remains, developers should prefer strconv.Itoa (or fmt.Sprint) for numeric‑to‑string conversion to avoid the rune‑conversion pitfall.
References
Go proposal #3939: https://github.com/golang/go/issues/3939
Language Change Review Meeting #33892: https://github.com/golang/go/issues/33892
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
TonyBai
Tony Bai's tech world (tonybai.com). Not satisfied with just "knowing how", we strive for mastery. Focused on Go language internals, high-quality engineering practices, and cloud‑native architecture, exploring cutting‑edge intersections of Go and AI. Gophers who pursue technology are welcome—follow me and evolve with Go.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
