Architecture-specific Numeric Types
February 21, 2023
In addition to the architecture-independent numeric types, Go provides three architecture-specific numeric types. Although there are far fewer of them, they often get a lot more usage.
Numeric Types
…
There is also a set of predeclared integer types with implementation-specific sizes:
uint either 32 or 64 bits int same size as uint uintptr an unsigned integer large enough to store the uninterpreted bits of a pointer value
What does it mean for a type’s size to be architecture-dependent?
Well, it means that if you compile you code to run on, say, the 386
architecture, then int
, and uint
will hold 32 bits of data. But if you compile for the amd64
architecture, the same types will hold 64 bits of data.
But importantly, just because you may be compiling and running your code for the 386
architecture doesn’t mean that int
and int32
are the same!
… Explicit conversions are required when different numeric types are mixed in an expression or assignment. For instance,
int32
andint
are not the same type even though they may have the same size on a particular architecture.
Okay, but why bother with this complexity?
In a word: efficiency.
While any CPU (not counting truly ancient ones) can handle both 32-bit and 64-bit numbers, they can’t do it with equal efficiency.
Manipulating 64-bit numbers on the 386
architecture involves manipulating two sets of 32-bit numbers, because the CPU’s native operations operate only on 32-bit numbers at a time.
So when should you use these architecture-specific types? Well, most of the time, actually. Generally, use int
and uint
for for loops or internal counters, unless there’s a risk of overflow (you’re counting large numbers that could exceed the min/max values of a 32-bit value), or you know you need a specific format for compatibility (i.e. writing the exact memory bits to the network or disk or similar).
Quotes from The Go Programming Language Specification, Version of January 19, 2023
Related Content

Empty structs
We finally we have enough knowledge for the EBNF format not to seem completely foreign, so let’s jump back and take a look at that, with the examples provided in the spec… Struct types … StructType = "struct" "{" { FieldDecl ";" } "}" . FieldDecl = (IdentifierList Type | EmbeddedField) [ Tag ] . EmbeddedField = [ "*" ] TypeName [ TypeArgs ] . Tag = string_lit . // An empty struct.

Struct tags
Struct types … A field declaration may be followed by an optional string literal tag, which becomes an attribute for all the fields in the corresponding field declaration. An empty tag string is equivalent to an absent tag. The tags are made visible through a reflection interface and take part in type identity for structs but are otherwise ignored. struct { x, y float64 "" // an empty tag string is like an absent tag name string "any string is permitted as a tag" _ [4]byte "ceci n'est pas un champ de structure" } // A struct corresponding to a TimeStamp protocol buffer.

Struct method promotion
Yesterday we saw an example of struct field promotion. But methods (which we haven’t really discussed yet) can also be promoted. Struct types … Given a struct type S and a named type T, promoted methods are included in the method set of the struct as follows: If S contains an embedded field T, the method sets of S and *S both include promoted methods with receiver T. The method set of *S also includes promoted methods with receiver *T.