Go: Conversions

Basics

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:

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

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

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

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

string([]byte{97, 230, 151, 165}) // "a日"
[]byte("a日")                     // []byte{97, 230, 151, 165}

Strings and rune slices

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.

The built-in package unsafe, known to the compiler, provides facilities for low-level programming including operations that violate the type system. A package using unsafe must be vetted manually for type safety and may not be portable. The Go Programming Language Specification: Package unsafe

Comments

Be the first to comment!