Type Conversion
Understand why Go requires explicit type conversion, how to convert between numeric types, and how to use the strconv package.
On this page 12 sections
Introduction
Many languages will quietly convert an integer to a float, or a number to a string, whenever it seems convenient. Go refuses to do this. Every type conversion in Go must be written explicitly, which trades a little extra typing for a lot fewer subtle bugs.
This lesson explains why Go takes this approach, how to convert between numeric types, and how the strconv package handles conversions between strings and numbers.
Why Go Has No Implicit Conversion
In many languages, mixing an int and a float in an expression silently "just works," with the language deciding how to combine them behind the scenes. Go's designers considered this a hidden source of bugs and confusion, so Go requires you to convert types explicitly every time — even between two closely related numeric types like int and int64.
package main
import "fmt"
func main() { var a int = 10 var b float64 = 3.5
// This line would NOT compile: // result := a + b // mismatched types int and float64
result := float64(a) + b // explicit conversion required fmt.Println(result)}Click Run to see what this code prints.
Converting Between Numeric Types
To convert between numeric types, call the target type as if it were a function, passing in the value you want to convert.
package main
import "fmt"
func main() { var i int = 42 var f float64 = float64(i) var u uint = uint(f) var i8 int8 = int8(i)
fmt.Println(i, f, u, i8)}Click Run to see what this code prints.
Converting a float to an int truncates the decimal portion (3.9 becomes 3, not 4). Converting a large value into a smaller type (e.g. int64 into int8) can silently overflow and produce an unexpected value — Go will not warn you at runtime.
Converting Numbers to Strings
You might expect string(65) to convert the number to the text "65" — but in Go, converting an integer directly to string instead interprets it as a Unicode code point (producing "A" for 65), which is rarely what you want for everyday number-to-text conversion. Instead, use the strconv package.
package main
import ( "fmt" "strconv")
func main() { score := 95 text := strconv.Itoa(score) // "Integer to ASCII"
fmt.Println("Score: " + text) fmt.Println(len(text))}Click Run to see what this code prints.
Converting Strings to Numbers
To go the other direction — parsing a string into a number — use strconv.Atoi for integers, or strconv.ParseFloat for floating-point numbers.
package main
import ( "fmt" "strconv")
func main() { input := "128" number, err := strconv.Atoi(input) if err != nil { fmt.Println("Conversion failed:", err) return } fmt.Println(number + 2)}Click Run to see what this code prints.
Handling Conversion Errors
Unlike a simple type conversion (which always succeeds), parsing user-provided or external text into a number can fail — the string might not actually be a valid number. That's why strconv.Atoi and similar functions return two values: the parsed result, and an error that is nil on success.
package main
import ( "fmt" "strconv")
func main() { input := "not-a-number" _, err := strconv.Atoi(input) if err != nil { fmt.Println("Error:", err) }}Click Run to see what this code prints.
Converting Between string, []byte, and []rune
Converting a string to a byte slice or rune slice (and back) is also done through explicit conversion syntax, and is common when you need to modify text, since Go strings themselves are immutable.
package main
import "fmt"
func main() { original := "Go" bytes := []byte(original) runes := []rune(original)
bytes[0] = 'N' // modify the byte slice fmt.Println(string(bytes)) fmt.Println(len(runes))}Click Run to see what this code prints.
Common Mistakes
- Using
string(65)to try to turn a number into its text digits — this actually produces the Unicode character "A", not "65". - Ignoring the error returned by
strconv.Atoi— a malformed string will cause it to fail, and the returned number will be 0. - Converting a large numeric type into a smaller one without checking bounds, risking silent overflow.
- Forgetting that converting float to int truncates rather than rounds (3.9 becomes 3, not 4).
Best Practices
- Always check the
errorreturned by strconv functions before using the parsed value. - Use
strconv.Itoa/strconv.Atoifor the common int-string round trip; reach forstrconv.ParseFloat/FormatFloatfor floats. - Be explicit and deliberate about which numeric type you convert to, especially when precision or range matters.
- When you need to round a float to an int rather than truncate, use
math.Roundbefore converting.
Frequently Asked Questions
Go's designers wanted to eliminate an entire class of subtle bugs caused by silent, "convenient" conversions between types with different precision or behavior. Explicit conversion makes intent clear and forces you to consciously handle edge cases.
It stands for "string conversion" — it is the standard library package dedicated to converting between strings and other basic types like int, float64, and bool.
Converting an integer directly to string in Go treats the number as a Unicode code point, not as text digits. 65 is the Unicode code point for the letter "A". Use strconv.Itoa to get the digit text "65" instead.
Key Takeaways
- Go requires explicit conversion between all differing types, even closely related numeric ones.
- Numeric conversions use
TargetType(value)syntax, e.g.float64(x). - The
strconvpackage handles string-to-number and number-to-string conversions. - strconv functions that can fail return an error value that must be checked.
- Converting int(65) to string via
string()gives a Unicode character, not digit text — use strconv.Itoa instead.
Summary
You now understand why Go requires explicit conversions, how to convert between numeric types, and how to safely convert strings and numbers using strconv. Next, you'll cover Go's arithmetic, comparison, logical, and bitwise operators.