跪拜 Guibai
← All articles
Go

Go's Strict Type System Hits a JavaScript Developer: Variables, Zero Values, and the Cost of Implicit Conversion

By 他们叫我秃子 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Backend services consume string-shaped data from HTTP parameters, and Go forces every conversion to be explicit and error-checked. A developer who skips the `err` check after `strconv.Atoi` will ship a zero where a parse failure occurred, corrupting pagination, pricing, or query logic with no stack trace to flag it.

Summary

The first real Go project surfaces a cascade of compile-time rejections that JavaScript and TypeScript developers rarely encounter. Unused local variables and imports stop the build outright. The `:=` short declaration creates new variables inside blocks, silently shadowing outer names when `=` was intended. Numeric types refuse to interoperate: adding an int to a float64 requires an explicit cast, and converting float64 to int truncates toward zero without rounding.

String conversion delivers the sharpest surprise. `string(65)` produces `"A"`, not `"65"`, because Go treats the integer as a Unicode code point. Getting a decimal string requires `strconv.Itoa`, and parsing back with `strconv.Atoi` returns both a result and an error. A failed parse yields the int zero value `0`, which is indistinguishable from a successful parse of `"0"` unless the error is checked.

These constraints form a consistent philosophy: the compiler refuses to guess intent. Every type coercion, every unused symbol, and every shadowed variable must be resolved explicitly before the program runs. For a developer accustomed to JavaScript's permissive coercion, the friction is immediate, but it eliminates entire categories of runtime surprise.

Takeaways
Unused local variables and unused imports are compile-time errors in Go, not lint warnings.
`:=` declares a new variable; reusing it on an existing name inside a block creates a shadow, not a reassignment.
`string(65)` converts the integer to a Unicode code point (`"A"`), not to the decimal string `"65"`.
Use `strconv.Itoa` for int-to-string and `strconv.Atoi` for string-to-int; the latter returns an error that must be checked.
A failed `strconv.Atoi` returns the int zero value `0`, which is identical to a successful parse of `"0"`.
Adding an int and a float64 is a compile error; an explicit cast like `float64(age) + progress` is required.
Casting float64 to int truncates toward zero: `int(19.99)` is `19`, `int(-19.99)` is `-19`.
Package-level variables cannot use `:=`; they must be declared with `var`.
`go build` produces a static binary that does not auto-update when source changes; re-run it after edits.
Go's zero values (`""`, `0`, `0.0`, `false`) replace JavaScript's `undefined` for uninitialized variables.
Conclusions

Go treats unused symbols as a compilation failure, which feels pedantic during prototyping but prevents dead code from accumulating across a large module graph.

The `string()` vs `strconv.Itoa` distinction is a recurring trap for developers coming from JavaScript, Python, or Ruby, where a single `String()` or `str()` call handles decimal formatting.

Variable shadowing with `:=` inside blocks is syntactically legal and produces no warning, making it a stealthier source of bugs than the loudly enforced type errors.

Go's refusal to coerce numeric types forces a decision about precision loss at the call site, which matters acutely for financial calculations where implicit float conversion would silently drop cents.

Concepts & terms
Zero value
The default value a variable holds when declared without an explicit initializer. Each type has a fixed zero value: 0 for int and float64, "" for string, false for bool. This eliminates uninitialized-memory bugs but means a zero result from a failed parse is ambiguous without checking the accompanying error.
Variable shadowing
Declaring a new variable with the same name inside an inner block (e.g., using `:=` inside an if statement). The inner variable hides the outer one for the block's duration; the outer variable remains unchanged. This is a common source of logic errors when `=` was intended.
strconv
Go's standard library package for converting strings to and from basic data types. Key functions include `Atoi` (string to int), `Itoa` (int to string), `ParseFloat` (string to float64), and `FormatFloat` (float64 to string). Unlike a bare `string()` cast, these functions handle decimal representation and return explicit errors.
Unicode code point conversion
In Go, `string(65)` interprets the integer as a Unicode code point and returns the corresponding character (`A`). This is distinct from formatting the integer as a decimal string, which requires `strconv.Itoa` or `fmt.Sprintf`.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗