1

I'm trying to figure out how to change a multidimensional slice by reference.

func main() {

    matrix := [][]int{
        {1, 0, 0},
        {1, 0, 0},
        {0, 1, 1},
    }
    fmt.Println("Before")
    printMatrix(matrix)
    changeMatrixByReference(&matrix)

    fmt.Println("After")
    printMatrix(matrix)
}

func changeMatrixByReference(matrix *[][]int) {
    //&matrix[0][0] = 3
}

func printMatrix(matrix [][]int) {
    for i := 0; i < len(matrix); i++ {
        for j := 0; j < len(matrix[0]); j++ {
            fmt.Printf("%d", matrix[i][j])
        }
        fmt.Println("")
    }
}

How can I change the matrix 2d slice inside the function changeMatrixByReference? I expect when printMatrix runs the second time matrix[0][0] becomes 3.

alif
  • 33
  • 4
  • 1
    To de-reference a pointer use the `*` (pointer indirection operator), not `&`. That is, `(*matrix)[0][0] = 3`. https://play.golang.com/p/csHBqcCwF-b – mkopriva Jun 09 '19 at 08:20
  • 1
    ... read more here: https://golang.org/ref/spec#Address_operators – mkopriva Jun 09 '19 at 08:23

1 Answers1

1

To set matrix[0][0] to 3, using pointer dereferencing:

(*matrix)[0][0] = 3

Try this:

package main

import "fmt"

func main() {

    matrix := [][]int{
        {1, 0, 0},
        {1, 0, 0},
        {0, 1, 1},
    }
    fmt.Println("Before")
    printMatrix(matrix)
    changeMatrixByReference(&matrix)

    fmt.Println("After")
    printMatrix(matrix)
}

func changeMatrixByReference(matrix *[][]int) {
    (*matrix)[0][0] = 3
}

func printMatrix(matrix [][]int) {
    for i := 0; i < len(matrix); i++ {
        for j := 0; j < len(matrix[0]); j++ {
            fmt.Printf("%d", matrix[i][j])
        }
        fmt.Println("")
    }
}


For as long as you don't modify the slice header (like when adding element), you don't need a pointer, elements accessed by their index are stored in a backing array for which the slice header holds a pointer for you:
Try this:

package main

import "fmt"

func main() {

    matrix := [][]int{
        {1, 0, 0},
        {1, 0, 0},
        {0, 1, 1},
    }
    fmt.Println("Before")
    printMatrix(matrix)
    changeMatrixByReference(matrix)

    fmt.Println("After")
    printMatrix(matrix)
}

func changeMatrixByReference(matrix [][]int) {
    matrix[0][0] = 3
}

func printMatrix(matrix [][]int) {
    for i := 0; i < len(matrix); i++ {
        for j := 0; j < len(matrix[0]); j++ {
            fmt.Printf("%d", matrix[i][j])
        }
        fmt.Println("")
    }
}

Output:

Before
100
100
011
After
300
100
011
wasmup
  • 14,541
  • 6
  • 42
  • 58
  • 1
    the note in this response is very important! slice types are *already pointer types* (see: https://www.geeksforgeeks.org/slices-in-golang/), so you don't need to give pointers to them. Go also has Arrays, which are more like traditional array types but should very rarely be used – user1034533 Dec 18 '19 at 20:47