Contents

Composite Data Types

Arrays

Arrays in Go are collections of elements of the same type with a fixed length. The length of an array is a part of its type, meaning that [3]int and [4]int are considered different types. Arrays are stored contiguously in memory, and each element can be accessed using an index. Once an array is defined, its size cannot be changed. Arrays are useful when you know the exact number of elements you need to store and when you want to work with data in a fixed structure.

Example:

				
					var arr [3]int = [3]int{1, 2, 3}
fmt.Println(arr)  // Output: [1 2 3]

// Accessing an element
fmt.Println(arr[0])  // Output: 1

// Modifying an element
arr[2] = 10
fmt.Println(arr)  // Output: [1 2 10]
				
			

Slices

Slices are a more flexible and powerful alternative to arrays. While they are built on top of arrays, slices provide dynamic sizing, which means their length can grow or shrink. A slice is essentially a descriptor of an underlying array that includes a pointer to the array, the length of the slice, and its capacity. Slices are widely used in Go because of their flexibility. You can create a slice by slicing an array or by using the built-in make function. You can also append new elements to a slice using the append function, which might cause the slice to point to a new array if the original array is too small to accommodate the new elements.

Example:

				
					slice := []int{1, 2, 3}
fmt.Println(slice)  // Output: [1 2 3]

// Append an element to the slice
slice = append(slice, 4)
fmt.Println(slice)  // Output: [1 2 3 4]

// Slicing an existing slice
subSlice := slice[1:3]
fmt.Println(subSlice)  // Output: [2 3]

// Modifying an element in the slice
slice[0] = 10
fmt.Println(slice)  // Output: [10 2 3 4]
				
			

Maps

Maps in Go are unordered collections of key-value pairs, where each key is unique. They are implemented using a hash table, making them efficient for lookups, inserts, and deletes based on the key. The key type must be comparable, meaning you can use operators like == or != with it, while the value type can be any type. Maps are useful for scenarios where you need to associate values with keys, like storing information about a set of students where each student has a unique ID.

Example

				
					m := map[string]int{"a": 1, "b": 2}
fmt.Println(m)  // Output: map[a:1 b:2]

// Accessing a value by key
fmt.Println(m["a"])  // Output: 1

// Adding a new key-value pair
m["c"] = 3
fmt.Println(m)  // Output: map[a:1 b:2 c:3]

// Deleting a key-value pair
delete(m, "b")
fmt.Println(m)  // Output: map[a:1 c:3]

// Checking if a key exists
value, exists := m["b"]
fmt.Println(value, exists)  // Output: 0 false

				
			

Structs

Structs in Go are user-defined types that group together fields, which can be of different types. Structs are similar to classes in object-oriented languages but do not include methods by themselves. They are used to create more complex data types that represent real-world entities, such as a Person, Car, or Book. Each field in a struct is accessed using the dot . operator. Structs are powerful when you need to create types that combine multiple pieces of data into a single unit. Go supports creating methods on structs, which allows for encapsulation of behavior related to the data.

Example:

				
					type Person struct {
    Name string
    Age  int
}

// Creating a struct instance
p := Person{Name: "John", Age: 30}
fmt.Println(p)  // Output: {John 30}

// Accessing struct fields
fmt.Println(p.Name)  // Output: John
fmt.Println(p.Age)   // Output: 30

// Modifying a struct field
p.Age = 31
fmt.Println(p)  // Output: {John 31}

// Creating a pointer to a struct
pPtr := &p
pPtr.Name = "Doe"
fmt.Println(p)  // Output: {Doe 31}