切片数组 - GO

时间:2017-01-28 06:49:25

标签: arrays go slice

1)

对于下面的切片声明,

var a [][3]string

创建一个切片(a),指向3个字符串的数组,len(a) = 3cap(a) =3但不是cap(a) >= 3

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

创建5个切片,其中每个切片(比如a[0])指向3个字符串的数组,len(a[0]) = 3cap(a[0]) = 3

2)

对于切片声明,

var b [][3][6]string

创建一个切片(b),指向3个数组,每个数组包含6个字符串,其中len(b) = 3cap(b) =3

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

创建5个切片,其中每个切片(比如b[0])指向3个数组,每个数组包含6个字符串

在这两种情况下,在制作切片后,我说,创建了5个切片,

考虑到语法,下面是我的两个问题,

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

我的问题:

1)

是5个切片,每个切片(a[0])是3个字符串的数组吗?

是一个单个切片(a)指向5个每个3个字符串的数组吗?

2)

我如何知道元素的类型?切片还是数组?

1)在这种情况下,必须谨慎使用“数组”术语。

2)与C

不同,GO中没有隐式指针

2 个答案:

答案 0 :(得分:3)

切片和数组是两种不同的类型:内存中的数组是相同类型的连续值序列。在Go中,类型具有固定大小。例如,在C ++和

中存在相同的概念
int x[5]; // C and C++
x [5]int  // Go

基本上是相同的(不是100%相同,因为C和C ++中的数组是"第二类公民"并且在一些地方表现得很奇怪,Go在这方面更加统一)。

Go中的切片是" view"一个数组的一部分,并且或多或少等同于一个C ++结构,其中包含指向第一个元素的指针,一些使用过的元素(相对于第一个)和一些可用元素(相对于第一个)

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

// Go
var x []int

Make特殊功能能够创建与新创建的阵列相关的切片,给定大小和可选容量:

// 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)

切片可以在O(1)中有效传递(独立于大小/容量),你也可以在O(1)中获取切片的子切片...注意Go是垃圾收集,在C ++中也需要一些额外的工作(例如,还要保留指向原始数组对象的指针及其在切片中的大小)。

您当然可以拥有切片数组,切片切片,数组切片和数组数组。但请注意,Go Make仅用于创建切片(和贴图)而不是数组...

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}}

虽然例如yz in the playground在使用[[1, 2], [3, 4], [5, 6]]时看起来相同fmt.Println,但它们的类型非常不同,例如你可以使用

将新对添加到y
y = append(y, [2]int{7, 8})  // now [[1, 2], [3, 4], [5, 6], [7, 8]]

您可以使用

增加z的第一个元素的长度
z[0] = append(z[0], 99) // now [[1, 2, 99], [3, 4], [5, 6]]

但你无法向z添加新元素(它是一个数组),你不能扩展y的元素(因为元素是数组)

答案 1 :(得分:2)

  

1)考虑语法,

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

是5个切片,每个切片(a [0])是3个字符串的数组吗?

     

     

是单个切片(a)指向5个每个3个字符串的数组吗?

它是一个包含5个元素的单个切片,其中每个元素是一个包含3个字符串的数组。

  

2)

     

我如何知道元素的类型?切片还是数组?

切片和数组是不同的类型。您不能互换地将数组和切片分配给同一个变量,因此如果声明将其声明为数组,则将其声明为数组(如果它将其声明为切片),则为切片。如果括号([5]string)中的数字是一个数组,如果括号为空([]string)则为一个切片。

  

2)对于切片声明,

var b [][3][6]string
     

创建一个切片(b),指向每个包含6个字符串的3个数组,   其中len(b)= 3且cap(b)= 3

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

创建5个切片,其中每个切片(比如b [0])指向3个数组,每个数组包含6个字符串

没有。以前的代码只是声明一个变量,它还没有一个切片。后代码使用五个元素创建一个切片。