Arrays,slices,maps

Arrays & structs are passed by value. To pass by reference need to add & sign. Examples:

func main() {
    a := [3]int{1,2,3}
    b := a
    b[0] = 2
    // Will print [1,2,3] [2,2,3]
    fmt.Println(a,b)

    r := &a
    r[0] = 3
    // Will print [3,2,3] &[3,2,3]
    fmt.Println(a,r)
}

Slices & maps are passed by reference. Example:

func main() {
    a := []int{1,2,3}
    b := a
    b[0] = 2
    // Will print [2,2,3] [2,2,3]
    fmt.Println(a,b)

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

Changing slice value will modify underlying array:

func main() {
    a := [3]int{1, 2, 3}
    // Slice will contain values from index 1 til end: [2,3]
    s := a[1:]
    s[0] = 3
    // Will print [1,3,3]
    fmt.Println(a, s)
}

Accessing map by index always returns value and dont fail with error if key doesn't exists. To check if key exists use second variable while retrieve value:

func main() {
    studentsAges := map[string]int{
        "John Doe":      19,
        "Jane Doe":      18,
        "James Summers": 20,
    }
    notExistingStudentAge := studentsAges["Johnatan Do"]
    // Output: 0. Because zero is default value for int
    fmt.Println("Not existing key 1 example ", notExistingStudentAge)
    // variable name ok is not required but recommended by convention
    if notExistingStudentAge2, ok := studentsAges["Johnatan Do"]; ok {
        // This wouldn't be reached
        fmt.Println("Not existing key 2 example ", notExistingStudentAge2)
    }
}