Go is a strongly-typed language, which means any language element that stores (or expression that produces) a value has a type associated with it. In this chapter, readers will learn about the features of the type system as they explore the common data types supported by the language as outlined in the following:
To help launch the conversation about types, let us take a peek at the types available. Go implements a simple type system that provides programmers direct control over how memory is allocated and laid out. When a program declares a variable, two things must take place:
This allows the type system to allocate the number of bytes necessary to store the declared value. The memory layout for declared variables maps directly to their declared types. There is no type boxing or automatic type conversion that takes place. The space you expect to be allocated is actually what gets reserved in memory.
To demonstrate this fact, the following program uses a special package called unsafe
to circumvent the type system and extract memory size information for declared variables. It is important to note that this is purely illustrative as most programs do not commonly make use of the unsafe
package.
package main import ( "fmt" "unsafe" ) var ( a uint8 = 72 b int32 = 240 c uint64 = 1234564321 d float32 = 12432345.232 e int64 = -1233453443434 f float64 = -1.43555622362467 g int16 = 32000 h [5]rune = [5]rune{'O', 'n', 'T', 'o', 'p'} ) func main() { fmt.Printf("a = %v [%T, %d bits] ", a, a, unsafe.Sizeof(a)*8) fmt.Printf("b = %v [%T, %d bits] ", b, b, unsafe.Sizeof(b)*8) fmt.Printf("c = %v [%T, %d bits] ", c, c, unsafe.Sizeof(c)*8) fmt.Printf("d = %v [%T, %d bits] ", d, d, unsafe.Sizeof(d)*8) fmt.Printf("e = %v [%T, %d bits] ", e, e, unsafe.Sizeof(e)*8) fmt.Printf("f = %v [%T, %d bits] ", f, f, unsafe.Sizeof(f)*8) fmt.Printf("g = %v [%T, %d bits] ", g, g, unsafe.Sizeof(g)*8) fmt.Printf("h = %v [%T, %d bits] ", h, h, unsafe.Sizeof(h)*8) }
golang.fyi/ch04/alloc.go
When the program is executed, it prints out the amount of memory (in bits) consumed by each declared variable:
$>go run alloc.go a = 72 [uint8, 8 bits] b = 240 [int32, 32 bits] c = 1234564321 [uint64, 64 bits] d = 1.2432345e+07 [float32, 32 bits] e = -1233453443434 [int64, 64 bits] f = -1.43555622362467 [float64, 64 bits] g = 32000 [int16, 16 bits] h = [79 110 84 111 112] [[5]int32, 160 bits]
From the preceding output, we can see that variable a
(of type uint8
) will be stored using eight bits (or one byte), variable b
using 32 bits (or four bytes), and so on. With the ability to influence memory consumption coupled with Go's support for pointer types, programmers are able to strongly control how memory is allocated and consumed in their programs.
This chapter will cover the types listed in the following table. They include basic types such as numeric, Boolean, and strings:
Type |
Description |
|
Type for storing text values |
|
An integer type (int32) used to represent characters. |
|
Types for storing integral values. |
|
Types for storing floating point decimal values. |
|
Types that can represent complex numbers with both real and imaginary parts. |
|
Type for Boolean values. |
|
A type that represents a memory address where a value of type T is stored. |
The remaining types supported by Go, such as those listed in the following table, include composite, interface, function, and channels. They are covered later in chapters dedicated to their respective topics.
Type |
Description |
Array
|
An ordered collection of fixed size |
Slice |
A collection of unspecified size of numerically indexed sequence of elements of type |
|
A structure is a composite type composed of elements known as fields (think of an object). |
|
An unordered sequence of elements of type |
|
A named set of function declarations that define a set of operations that can be implemented by other types. |
|
A type that represents all functions with a given parameter type |
|
A type for an internal communication channel to send or receive values of type |
3.139.240.119