In general, Go considers each type to be different. This means under normal circumstances, values of different types are not fungible in assignment, function parameters, and expression contexts. This is true for built-in and declared types. For instance, the following will cause a build error due to type mismatch:
package main import "fmt" type signal int func main() { var count int32 var actual int var test int64 = actual + count var sig signal var event int = sig fmt.Println(test) fmt.Println(event) }
golang.fyi/ch04/type_conv.go
The expression actual + count
causes a build time error because both variables are of different types. Even though variables actual
and count
are of numeric types and int32
and int
have the same memory representation, the compiler still rejects the expression.
The same is true for declared named types and their underlying types. The compiler will reject assignment var event int = sig
because type signal
is considered to be different from type int
. This is true even though signal
uses int
as its underlying type.
To cross type boundaries, Go supports a type conversion expression that converts value from one type to another. Type conversion is done using the following format:
<target_type>(<value or expression>)
The following code snippet fixes the previous example by converting the variables to the proper types:
type signal int func main() { var count int32 var actual int var test int32 = int32(actual) + count var sig signal var event int = int(sig) }
golang.fyi/ch04/type_conv2.go
Note that in the previous snippet assignment expression var test int32 = int32(actual) + count
converts variable actual
to the proper type to match the rest of the expression. Similarly, expression var event int = int(sig)
converts variable sig
to match the target type int
in the assignment.
The conversion expressions satisfy the assignment by explicitly changing the type of the enclosing values. Obviously, not all types can be converted from one to another. The following table summarizes common scenarios when type conversion is appropriate and allowed:
Description |
Code |
The target type and converted value are both simple numeric types. |
var i int var i2 int32 = int32(i) var re float64 = float64(i + int(i2)) |
The target type and the converted value are both complex numeric types. |
var cn64 complex64 var cn128 complex128 = complex128(cn64) |
The target type and converted value have the same underlying types. |
type signal int var sig signal var event int = int(sig) |
The target type is a string and the converted value is a valid integer type. |
a := string(72) b := string(int32(101)) c := string(rune(108)) |
The target type is string and the converted value is a slice of bytes, int32, or runes. |
msg0 := string([]byte{'H','i'}) msg1 := string([]rune{'Y','o','u','!'}) |
The target type is a slice of byte, int32, or rune values and the converted value is a string. |
data0 := []byte("Hello") data0 := []int32("World!") |
Additionally, the conversion rules also work when the target type and converted value are pointers that reference the same types. Besides these scenarios in the previous table, Go types cannot be explicitly converted. Any attempt to do so will result in a compilation error.
18.189.186.167