Data Types in Go
Understand Go data types: basic types (string, numbers, bool), zero values, composite types (structs, slices), any (interface{}), type checking with %T and reflect, and type assertions.
What Are Data Types?
Data types define what kind of value a variable can hold. Go is statically typed: every variable has a type that is fixed at compile time. A variable cannot hold a value of a different type.
1. Static Typing
Once a variable is declared with a type, it can only hold values of that type.
Basic (Primitive) Data Types
Go has a small set of basic types: strings, integers, floats, and booleans. Uninitialized variables get a zero value (e.g. 0 for numbers, "" for strings, false for bool).
1. string
Textual data. Strings are immutable sequences of bytes (UTF-8).
2. int and float64
Integers and floating-point numbers. Go has several sizes: int, int64, float32, float64.
3. bool
Boolean: true or false. Used in conditions and logic.
4. Zero Values
Uninitialized variables get a default "zero" value. Go has no undefined.
5. nil (Absence of Value)
Pointers, slices, maps, and other reference types have a zero value of nil when not initialized.
6. byte and rune
byte is uint8 (one byte). rune is int32 and represents a Unicode code point (one character).
Composite Types (Structs, Slices)
Structs and slices are used to group data. They are passed by value, but the value may contain a reference to underlying data.
1. Struct (Like an Object)
Structs group related fields (key-value–style data).
2. Slice (Ordered List)
A slice is a growable sequence of elements. Index starts from 0.
3. Functions as Values
Functions are first-class: you can assign them to variables and pass them around.
Printing the Data Type
Use `fmt.Printf` with the `%T` verb to print the type of a value. For more detail you can use the `reflect` package.
1. Using %T
The %T verb prints the type of the value.
Comparing Data Types
When you have a value whose type you need to check (e.g. from an interface), you can use `%T` with fmt.Sprintf, or the `reflect` package, or a type switch.
1. Type Check Using if
Compare the type string from reflect or %T.
2. Type Check Using switch (reflect)
Use a switch on the reflect kind to handle multiple types.
any and interface{}
In Go, `any` (or `interface{}`) is the empty interface: it has no methods, so every type satisfies it. A variable of type `any` can therefore hold a value of any type. Use it when you need to accept or store values whose type is not known at compile time (e.g. JSON, mixed-type containers).
1. What is any (and interface{})?
The empty interface has no methods; any type satisfies it. any is an alias for interface{}.
2. When to Use any
Use any when you need to accept or store values of unknown or mixed type.
Type Assertions and Type Switches
Variables of type `any` can hold any value. To use the value as a specific type, you use a type assertion `v.(Type)` or a type switch.
1. Checking a Slice Type with Type Assertion
Use a type assertion to see if an any holds a []int (or other slice type).
2. Checking a Custom Type (Struct) with Type Assertion
Use a type assertion to see if a value is a specific struct type (e.g. *User).
3. Type Switch for Multiple Types
A type switch is the cleanest way to handle several possible concrete types.