Recursive arrays

Today, our final note on array types, and when recursion of types is, and is not, permitted: Array types … An array type T may not have an element of type T, or of a type containing T as a component, directly or indirectly, if those containing types are only array or struct types. // invalid array types type ( T1 [10]T1 // element type of T1 is T1 T2 [10]struct{ f T2 } // T2 contains T2 as component of a struct T3 [10]T4 // T3 contains T3 as component of a struct in T4 T4 struct{ f T3 } // T4 contains T4 as component of array T3 in a struct ) // valid array types type ( T5 [10]*T5 // T5 contains T5 as component of a pointer T6 [10]func() T6 // T6 contains T6 as component of a function type T7 [10]struct{ f []T7 } // T7 contains T7 as component of a slice in a struct ) I think the explanation and provided examples are pretty clear.


N-dimensional arrays

There’s one sentence at the end of the paragraph yesterday about arrays, which I saved for today, as I think it deserves special attention: Array types … Array types are always one-dimensional but may be composed to form multi-dimensional types. [3][5]int [2][2][2]float64 // same as [2]([2]([2]float64)) The two examples provided do not represent a 2- and 3-dimensional array, therefore. Rather, they represent an array of arrays, and an array of arrays of arrays, respectively.


Array types

Arrays should not be a foreign concept to anyone who’s done programming before. But Go’s version of arrays has some peculiarities that often trip up beginners. Array types An array is a numbered sequence of elements of a single type, called the element type. The number of elements is called the length of the array and is never negative. ArrayType = "[" ArrayLength "]" ElementType . ArrayLength = Expression . ElementType = Type .


When a string's length is constant

String Types … The length of a string s can be discovered using the built-in function len. The length is a compile-time constant if the string is a constant. A string’s bytes can be accessed by integer indices 0 through len(s)-1. It is illegal to take the address of such an element; if s[i] is the i‘th byte of a string, &s[i] is invalid. There are a couple of nuggets in this paragraph.

Book Reviews

16 min read


What is the Best Book to Learn Go in 2023?

After reading every beginner's book I could find on Go, here is my recommended #1 book to help you learn the language.


Immutable strings

String Types A string type represents the set of string values. A string value is a (possibly empty) sequence of bytes. The number of bytes is called the length of the string and is never negative. Strings are immutable: once created, it is impossible to change the contents of a string. The predeclared string type is string; it is a defined type. Anyone who’s ever written even just “Hello, World” in virtually any language has had experience with strings.


Numeric type aliases

Numeric Types … byte alias for uint8 rune alias for int32 … To avoid portability issues all numeric types are defined types and thus distinct except byte, which is an alias for uint8, and rune, which is an alias for int32. As with other aliases in Go, this means that the same type simply has two (or perhaps more) identifiers, which are completely interchangeable. This means that byte is not a distinct type, simply backed by a uint8 type.

Subscribe to Boldly Go: Daily

Every day I'll send you advice to improve your understanding of Go. Don't miss out! I will respect your inbox, and honor my privacy policy.

Unsure? Browse the archive.


Architecture-specific Numeric Types

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?


Architecture-independent Numeric Types

Go provides several predeclared numeric types. Most of them have a fixed size, regardless of the architecture the program is compiled for or running on. Numeric Types An integer, floating-point, or complex type represents the set of integer, floating-point, or complex values, respectively. They are collectively called numeric types. The predeclared architecture-independent numeric types are: uint8 the set of all unsigned 8-bit integers (0 to 255) uint16 the set of all unsigned 16-bit integers (0 to 65535) uint32 the set of all unsigned 32-bit integers (0 to 4294967295) uint64 the set of all unsigned 64-bit integers (0 to 18446744073709551615) int8 the set of all signed 8-bit integers (-128 to 127) int16 the set of all signed 16-bit integers (-32768 to 32767) int32 the set of all signed 32-bit integers (-2147483648 to 2147483647) int64 the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807) float32 the set of all IEEE-754 32-bit floating-point numbers float64 the set of all IEEE-754 64-bit floating-point numbers complex64 the set of all complex numbers with float32 real and imaginary parts complex128 the set of all complex numbers with float64 real and imaginary parts byte alias for uint8 rune alias for int32 The value of an n-bit integer is n bits wide and represented using two’s complement arithmetic.


Boolean types

Boolean types A boolean type represents the set of Boolean truth values denoted by the predeclared constants true and false. The predeclared boolean type is bool; it is a defined type. No real surprises here. Go supports Boolean types. You can use the pre-declared Boolean type bool, or you can create your own types, backed by this type: type SpanishBool bool For an example why this might be useful, see my previous example.


Predeclared types

Types The language predeclares certain type names. Others are introduced with type declarations or type parameter lists. Composite types—array, struct, pointer, function, interface, slice, map, and channel types—may be constructed using type literals. Type declarations, type parameter lists, and type aliases are coming up later, so today we’re focused on the predeclared types. The list of predclared types would appear near the beginning of most intro to Go books (I would know, I just read and reviewed 11 of them!