Go: Conversions
The expression T(x)
converts the value x
to the type T
.
f := 5.1
i := int(f) // convert float to int
The conversion rules are extensive but predictable:
- all conversions between typed expressions must be explicitly stated,
- and illegal conversions are caught by the compiler.
Conversions between numbers and strings may change the representation and have a run-time cost. All other conversions only change the type but not the representation of x
.
Integers
- When converting to a shorter integer type, the value is truncated to fit in the result type's size.
- When converting to a longer integer type,
- if the value is a signed integer, it is sign extended;
- otherwise it is zero extended.
var a uint16 = 0x10fe // bit pattern: 0001 0000 1111 1110
// Truncation
b := int8(a) // -2 bit pattern: 1111 1110
// Sign extention
c := uint16(b) // 0xfffe bit pattern: 1111 1111 1111 1110
Floats
- When converting a floating-point number to an integer, the fraction is discarded (truncation towards zero).
- When converting an integer or floating-point number to a floating-point type, the result value is rounded to the precision specified by the destination type.
var f float64 = 1.9
n := int64(f) // 1
n = int64(-f) // -1
n = 1234567890
g := float32(n) // 1.234568e+09
Warning: In all non-constant conversions involving floating-point or complex values, if the result type cannot represent the value the conversion succeeds but the result value is implementation-dependent. The Go Programming Language Specification: Conversions
Integer to string
- When converting an integer to a string, the value is interpreted as a Unicode code point, and the resulting string will contain the character represented by that code point, encoded in UTF-8.
- If the value does not represent a valid code point (for instance if it's negative), the result will be
"\ufffd"
, the Unicode replacement character �.
string(97) // "a"
string(-1) // "\ufffd" == "\xef\xbf\xbd"
To get the decimal string representation of an integer, use the strconv.Itoa
function:
strconv.Itoa(97) // "97"
Strings and byte slices
- Converting a slice of bytes to a string type yields a string whose successive bytes are the elements of the slice.
- Converting a value of a string type to a slice of bytes type yields a slice whose successive elements are the bytes of the string.
string([]byte{97, 230, 151, 165}) // "a日"
[]byte("a日") // []byte{97, 230, 151, 165}
Strings and rune slices
- Converting a slice of runes to a string type yields a string that is the concatenation of the individual rune values converted to strings.
- Converting a value of a string type to a slice of runes type yields a slice containing the individual Unicode code points of the string.
string([]rune{97, 26085}) // "a日"
[]rune("a日") // []rune{97, 26085}
Underlying type
A non-constant value can be converted to type T
if it has the same underlying type as T
.
In this example, the underlying type of int64
, T1
, and T2
is int64
.
type (
T1 int64
T2 T1
)
It's idiomatic in Go to convert the type of an expression to access a specific method:
var n int64 = 12345
fmt.Println(n) // 12345
fmt.Println(time.Duration(n)) // 12.345µs
(The underlying type of time.Duration
is int64
, and the time.Duration
type has a String
method that returns the duration formatted as a time.)
Implicit conversions
The only implicit conversion in Go is when an untyped constant (see Go: Untyped numeric constants with no limits) is used in a situation where a type is required.
In this example the untyped literals 1
and 2
are implicitly converted:
var f float64
f = 1 // Same as: f = float64(1)
t := 2 * time.Second // Same as: t := time.Duration(2) * time.Second
(The implicit conversions are necessary since there is no mixing of numeric types in Go. You can only multiply a time.Duration
with another time.Duration
.)
When the type can't be inferred from the context, an untyped constant is converted to a bool
, int
, float64
, complex128
, string
or rune
depending on the syntactical format of the constant:
n := 1 // Same as: n := int(1)
f := 1.0 // Same as: f := float64(1.0)
s := "A" // Same as: s := string("A")
c := 'A' // Same as: c := rune('A')
Illegal implicit conversions are caught by the compiler:
var b byte = 256 // Same as: var b byte = byte(256)
../main.go:2:6: constant 256 overflows byte
Pointers
The Go compiler does not allow conversions between pointers and integers. The package unsafe
implements this functionality under restricted circumstances.