-3

In the below code:

package main

import "fmt"

func main() {
    fmt.Println("Simple array")
    arrayInt := []int{1, 2, 3, 4}
    fmt.Println(arrayInt, "\n")

    fmt.Println("Simple slice")
    sliceInt := arrayInt[:]
    fmt.Println(sliceInt, "\n")

    fmt.Println("Array of arrays")
    twoDimArray := [3][4]int{
        {1, 1, 1, 1},
        {2, 2, 2, 2},
        {3, 3, 3, 3},
    }
    fmt.Println(twoDimArray, "\n")

    fmt.Println("Array of slices")
    var arrayOfSlice [3][]int
    for i, _ := range twoDimArray {
        arrayOfSlice[i] = twoDimArray[i][:]
    }
    fmt.Println(arrayOfSlice, "\n")

    fmt.Println("Slice of arrays")
    var sliceOfArrays [][4]int
    sliceOfArrays = twoDimArray[:]
    fmt.Println(sliceOfArrays, "\n")

    fmt.Println("Slice of slices")
    var sliceOfSlice [][]int

}

twoDimArray need to be assigned to sliceOfSlice without creating underlying array(actual data) for sliceOfSlice

How to assign twoDimArray to sliceOfSlice?

icza
  • 389,944
  • 63
  • 907
  • 827
overexchange
  • 15,768
  • 30
  • 152
  • 347

1 Answers1

2

twoDimArray has element type [4]int and sliceOfSlice has element type []int. Those types are different, so there cannot be a sliceOfSlice value that shares the backing array with twoDimArray. A new backing array is required for twoDimArray, but its elements may be slice values sharing the backing array with the elements of twoDimArray, or more specifically having the elements of twoDimArray as their backing array.

You have to use a loop and slice each array element of the outer array, there is no shorthand:

fmt.Println("Slice of slices")
var sliceOfSlice [][]int
sliceOfSlice = make([][]int, len(twoDimArray))
for i := range twoDimArray {
    sliceOfSlice[i] = twoDimArray[i][:]
}
fmt.Println(sliceOfSlice, "\n")

This will output (try it on the Go Playground):

Slice of slices
[[1 1 1 1] [2 2 2 2] [3 3 3 3]] 

See related: What is a concise way to create a 2D slice in Go?

icza
  • 389,944
  • 63
  • 907
  • 827
  • So, If I say `sliceOfSlice[0] = make([]int, 4)` then underlying array(of size 4) gets created for `sliceOfSlice[0]`. Is that correct? – overexchange Aug 11 '20 at 19:30
  • @overexchange Yes, `make()` creates an array and slices it. And returns you the slice referencing the array created in it. – icza Aug 11 '20 at 19:31
  • After `sliceOfSlice = make([][]int, 3)` , the length `len(sliceOfSlice[0])` and capacity `len(sliceOfSlice[0])` gives 0. So, assigning `twoDimArray[0][:]` to `sliceOfSlice[0]` sets the slice descriptor(of `sliceOfSlice[0]`) with new values of len and cap. is that correct? – overexchange Aug 11 '20 at 19:36
  • @overexchange `make([][]int, 3)` creates a slice whose element type is `[]int`, and it will have 3 elements, but all elements are the zero value of the element type which is `nil`. So this `make()` returns a slice which contains 3 `nil` slices. `sliceOfSlice[0] = twoDimArray[0][:]` slices `twoDimArray[0]` and assigns this slice value to `sliceOfSlice[0]`. – icza Aug 11 '20 at 19:40
  • When you say syntax `twoDimArray[0][:]` slices, does this syntax create a temporary slice descriptor and this temporary file descriptor becomes `sliceOfSlice[0]`. Is that correct? – overexchange Aug 11 '20 at 19:48
  • @overexchange Not sure what you mean by "temporary". `twoDimArray[0][:]` is a [slice expression](https://golang.org/ref/spec#Slice_expressions) which results in a slice value (see [`reflect.SliceHeader`](https://golang.org/pkg/reflect/#SliceHeader)) which gets assigned to `sliceOfSlice[0]`. – icza Aug 11 '20 at 19:55
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/219634/discussion-between-overexchange-and-icza). – overexchange Aug 11 '20 at 19:56