简体   繁体   中英

Array of slices - GO

1)

For below slice declaration,

var a [][3]string

creates a single slice( a ) that points to array of 3 strings, len(a) = 3 and cap(a) =3 but not cap(a) >= 3

a = make([][3]string, 5)

creates 5 slices, where each slice(say a[0] ) points to array of 3 strings, len(a[0]) = 3 and cap(a[0]) = 3


2)

For slice declaration,

var b [][3][6]string

creates a single slice( b ) that points to 3 arrays of 6 strings each, where len(b) = 3 and cap(b) =3

b = make([][3][6]string, 5)

creates 5 slices, where each slice(say b[0] ) points to 3 arrays of 6 strings each


In both cases, after making slices, I said, creates 5 slices,


Considering the syntax, below are my two questions,

a = make([][3]string, 5)

My question:

1)

Is it 5 slices, where each slice( a[0] ) is array of 3 strings?

or

Is it a single slice( a ) pointing to 5 arrays of 3 strings each?

2)

How do I know the type of an element? slice or array?

1) In such scenarios, "array of" terminology has to be cautiously used.

2) There are no implicit pointers involved in GO unlike C

Slices and arrays are two different types: an array in memory is a contiguous sequences of values of the same type. In Go a type has a fixed size. The very same concept is present for example in C++ and

int x[5]; // C and C++
x [5]int  // Go

are basically the same thing (not 100% the same because arrays in C and C++ are "second class citizens" and behave strangely in a few places, Go is more uniform on that).

A slice in Go is instead a "view" of a portion of an array, and is more or less equivalent to a C++ structure with a pointer to the first element, a number of used elements (relative to first) and a number of available elements (relative to first)

// C++
template<typename T>
struct Slice {
    T *first;
    int size, capacity;
};
Slice<int> x{nullptr, 0, 0};

// Go
var x []int

The Make special function is able to create slices associated to newly created arrays, given size and optional capacity:

// C++
template<typename T>
Slice<T> make(int size, int capacity=-1) {
    if (capacity == -1) capacity = size;
    return Slice<T>{new T[capacity], size, capacity};
}

// Go
x := Make([]int, size, capacity)

Slices can be efficiently passed around in O(1) (independently on size/capacity) and you can also take a sub-slice of a slice in O(1)... note that Go is garbage collected, doing the same in C++ would require some extra work (for example also keeping a pointer to the original array object and its size in the slice).

You can of course have arrays of slices, slices of slices, slices of arrays and arrays of arrays. Note however that in Go Make is used only to create slices (and maps) not for arrays...

x := Make([][2]int, 3)   // a slice of 3 arrays of 2 ints each

// Same thing (except for content)
y := [][2]int{[2]int{1, 2},
              [2]int{3, 4},
              [2]int{5, 6}}

// An array of 3 slices of two ints each
z := [3][]int{[]int{1, 2},
              []int{3, 4},
              []int{5, 6}}

While for example both y and z in the playground would look the same [[1, 2], [3, 4], [5, 6]] when using fmt.Println , they are very different types, for example you can add a new pair to y with

y = append(y, [2]int{7, 8})  // now [[1, 2], [3, 4], [5, 6], [7, 8]]

and you can instead increase the length of first element of z with

z[0] = append(z[0], 99) // now [[1, 2, 99], [3, 4], [5, 6]]

but you cannot add new elements to z (it's an array) and you cannot extend an element of y (because elements are arrays)

1) Considering the syntax,

 a = make([][3]string, 5)

Is it 5 slices, where each slice(a[0]) is array of 3 strings?

or

Is it a single slice(a) pointing to 5 arrays of 3 strings each?

Its a single slice with 5 elements where each element is an array of 3 strings.

2)

How do I know the type of an element? slice or array?

Slices and arrays are different types. You can not interchangeably assign arrays and slices to the same variable, hence if the declaration declares it as an array, its an array, if it declares it as a slice, its a slice. If it has a number in the brackets ( [5]string ) its an array, if the brackets are empty ( []string ) its a slice.

2) For slice declaration,

 var b [][3][6]string

creates a single slice(b) that points to 3 arrays of 6 strings each, where len(b) = 3 and cap(b) =3

 b = make([][3][6]string, 5)

creates 5 slices, where each slice(say b[0]) points to 3 arrays of 6 strings each

No. Former code just declares a variable, it doesn't hold a slice yet. Latter code creates one slice with five elements.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM