Built-in, predeclared types

Basic types

Numeric types

Go has 12 numeric types group into three categories.

Integers

Type nameValue range
int8–128 to 127
int16–32768 to 32767
int32–2147483648 to 2147483647
int64–9223372036854775808 to 9223372036854775807
uint80 to 255
uint160 to 65535
uint320 to 4294967295
uint640 to 18446744073709551615
[[Go zero valuesZero value]] is 0 for all of them.

Integer literals defaults to int

Special integers

byte is an alias for uint8. It’s more common to use byte instead of uint8.

int is special in a way that on 32-bit CPU int is a 32-signed integer like int32, and on 64-bit CPUs int is an int64.

uint is the same as int, but it’s unsigned.

q Add more to that: rune and uintptr

Which integer to use
  • When working on a binary file format or network protocol that dictates some integer type, use that.
  • When working on a library, use generic types to support any integer type.
  • In all other cases use int, unless you have a specific reason to use a sized or unsigned integer type.

Floating-point types

Type nameLargest absolute valueSmallest (nonzero) absolute value
float323.40282346638528859811704183484516925440e+381.401298464324817070923729583289916131280e-45
float641.797693134862315708145274237317043567981e+3084.940656458412465441765687928682213723651e-324

Go uses the IEEE 754 specification, giving a large range and limited precision.

Floating-point literals have a float64 type by default.

Unless you need to be compatible with some format, use float64. It’s also more precise than float32.

Use floats in things like graphics, statistics and scientific operations. For everything else floats may not be a good fit because floating-point numbers have a huge range, but they store the nearest approximation, not every possible value in that range.

Operators

All operators can be used except %.

Dividing nonzero float by 0 returns +Inf or -Inf depending of the sign of the number.

Dividing a float = 0 by 0 returns NaN (Not a Number).

Go allows comparison with == and != on floats, but giving their inexact nature it may produce unexpected results. Instead define a maximum allowed variance and see if the difference between two floats is less than that. It’s called epsilon.

Complex types

Go has first-class support for complex numbers.

complex64 uses two float32 values to represent the real and imaginary part. complex128 uses two float64 values.

Both are declared with built-in complex() function.

var complexNum = complex(20.3, 10.2)
  • Untyped constants or literals for both function parameters will produce untyped complex literal that defaults to complex128.
  • Two float32 = complex64.
  • One is float32 and another is untyped or can fit into float32 = complex64.
  • Otherwise = complex128.

To extract the real and imaginary parts of the complex number use real() and imag() built-in functions respectively.

math/cmplx package has additional functions to manipulate complex numbers.

Runes

rune is an alias for uint8.

var myFirstInitial rune = 'J' // good - the type name matches the usage
var myLastInitial int32 = 'B' // bad - legal but confusing

Composite types

Array

Slice

String

Map

Structs

Basic types

bool
 
string
 
int  int8  int16  int32  int64
uint uint8 uint16 uint32 uint64 uintptr
 
byte // alias for uint8
 
rune // alias for int32
     // represents a Unicode code point
 
float32 float64
 
complex64 complex128

Structs

Type conversion

i := 42
f := float64(i)
u := uint(f)

Go doesn’t allow automatic type promotion, so you need to explicitly specify type conversion when dealing with integers or floats of different sizes.

var x int = 10
var y float64 = 30.2
var sum1 float64 = float64(x) + y
var sum2 int = x + int(y)
 
var x int = 10
var b byte = 100
var sum3 int = x + int(b)
var sum4 byte = byte(x) + b

Since all conversions are explicit, you can’t treat another Go type as a boolean. Because of that you need to explicitly check for zero value of a type, e.g. s == "" or x == 0.