Hi, my name is Walid, a backend developer who’s currently learning Go and sharing my journey by writing about it along the way.
Resource :
- The Go Programming Language book by Alan A. A. Donovan & Brian W. Kernighan
- Matt Holiday go course
Go is a statically typed language that provides a powerful and expressive type system, precise package initialization rules, native support for complex numbers, efficient handling of UTF-8, and a sophisticated constant generator known as iota. Understanding these concepts in depth will help you write robust and efficient Go programs.
Type Declarations in Go
In Go, the type keyword allows developers to define new types based on existing ones. This enables better code organization, improved readability, and stricter type safety by preventing unintended type mixing.
Defining Custom Types
type Age int // Defines a new type `Age` as an alias for `int`
var myAge Age = 25
Although Age is based on int, Go treats it as a separate type, meaning it cannot be used interchangeably with int without explicit conversion:
var years int = 30
myAge = Age(years) // Explicit conversion is required
Struct Type Declaration
Structs are composite types that allow grouping multiple fields together.
type Person struct {
Name string
Age int
}
This enables the creation of structured data models with meaningful field names.
Type Aliases vs. Custom Types
Introduced in Go 1.9, type aliases allow an existing type to be referred to by another name without creating a distinct type.
type MyInt = int // `MyInt` is an alias for `int`, not a new type
Unlike Age (a custom type), MyInt behaves exactly like int with no additional type safety.
Package Initialization
Package-level variables in Go are initialized in the order they are declared, ensuring deterministic behavior.
Initialization Order
var x = y + 2 // `y` must be initialized before `x`
var y = 10
Go guarantees that y is initialized before x, preventing undefined behavior.
The init Function
In addition to package-level variable initialization, Go provides an init function that executes automatically when the package is loaded.
func init() {
fmt.Println("Package initialized")
}
- The
initfunction is called once per package. - Multiple
initfunctions within a package execute in the order they appear. - Dependencies are resolved before execution, ensuring safe initialization across packages.
Basic Data Types in Go
Go's built-in types include:
-
Boolean:
bool(values:trueorfalse) -
Integers:
int, int8, int16, int32, int64 -
Unsigned Integers:
uint, uint8, uint16, uint32, uint64 -
Floating-Point Numbers:
float32, float64 -
Complex Numbers:
complex64, complex128 - Strings: UTF-8 encoded sequences of bytes
Type Size Considerations
Unlike C, Go’s int and uint types are platform-dependent:
- On 32-bit systems:
intis 32 bits - On 64-bit systems:
intis 64 bits
Complex Numbers in Go
Go natively supports complex numbers using complex64 and complex128.
Creating Complex Numbers
var c1 complex64 = 1 + 2i
c2 := complex(3, 4) // Using the built-in `complex` function
fmt.Println(c1, c2) // Output: (1+2i) (3+4i)
Extracting Real and Imaginary Parts
fmt.Println(real(c2)) // 3
fmt.Println(imag(c2)) // 4
Complex Arithmetic
c3 := c1 + c2
c4 := c1 * c2
fmt.Println(c3, c4)
This makes Go ideal for scientific computing and signal processing.
UTF-8 and Strings
Go uses UTF-8 encoded strings by default, ensuring efficient and flexible text handling.
String Length and Runes
s := "Hello, 世界"
fmt.Println(len(s)) // Outputs number of bytes, not characters
fmt.Println([]rune(s)) // Converts string to runes
fmt.Println(string(s[7:])) // Slices work at the byte level
Go strings are immutable, meaning operations that modify strings return new copies.
Working with Unicode
The unicode package provides utilities for character classification and transformation.
import "unicode"
fmt.Println(unicode.IsDigit('5')) // true
fmt.Println(unicode.IsLetter('A')) // true
The Constant Generator iota
iota is a unique identifier used for defining incrementing constants efficiently. It is often used for enumerations.
Simple iota Example
const (
A = iota // 0
B // 1
C // 2
)
Each successive constant increases by one.
Custom Increments
const (
KB = 1 << (10 * iota) // 1024
MB // 1048576
GB // 1073741824
TB // 1099511627776
)
Here, iota generates bit-shifted values representing storage sizes.
Using iota with Bit Flags
const (
Read = 1 << iota // 1
Write // 2
Exec // 4
)
This is useful for defining permission masks and other bitwise configurations.
Conclusion
Go's type system, initialization rules, built-in support for complex numbers, UTF-8 handling, and iota make it a powerful and expressive language. Understanding these fundamental concepts allows developers to write more efficient, type-safe, and readable code. Whether you're dealing with large-scale data processing, low-level system programming, or high-performance computing, Go's design ensures clarity and maintainability.
Top comments (0)