Go数组与切片

260 阅读3分钟

数组

概念上讲,golang数组与其他静态语言数组没有什么不同。都是具有相同唯一类型的一组已编号且长度固定的数据项序列(弱类型语言如javascript除外,它允许数组元素的类型可以不唯一,长度也是动态变化的)。所以,要想创建一个数组,必须先指定类型和长度。

创建一个整数型,长度是10的数组:

var array [10] int

我们没有给这些元素赋值,那么它们都是零值。整数的零值是0

创建并初始化:

var array = [5] int{1,2,3,4,5}

下面是error code,花括号里面的个数不能大于声明的个数。

var array = [5] int{1,2,3,4,5,6}

可以省略大小,但是要有花括号

var array = [...] int{1,2,3,4,5,6} // 数组长度是6
var array = [...] int{} // 数组长度是0

访问元素

func main(){
	var array = [...] int{1,2,3,4,5}
	for i:=0;i<len(array);i++{
		fmt.Println(array[i])
	}
}

二维数组

二维数组本质上也是由一维数组组成。

var array [2][3] int
/**
* println as below:
* [0,0,0]
* [0,0,0]
*/

行为与其他语言一致,多维以此类推。

切片

golang切片是对数组的抽象!用惯了javascript的开发者,比如我,就不适应不可变长数组。golang数组的长度不可改变,在特定场景中这样的数据结构真的是太难受了。还好它提供了一种“动态数组”,相比而言,它的长度是可变的,可以追加元素。

定义切片的几个姿势

1. var slice []int // 不需要说明长度!nice~~
2. var slice []int = make([]int, 1) // 第二个参数是指定的len
3. var slice []int = make([]int, 1,10) // 第三个参数是指定的capacity
4. slice := make([]int,1,10) // 简写

前面三种方式的type,必须和后面的保持一致,否则报错!

切片的初始化

slice :=[] int {1,2,3 } // []表示是切片类型,{1,2,3}初始化值依次是1,2,3.其cap=len=3

slice := arr[:] // 初始化切片,是数组arr的【引用】

slice := arr[startIndex:endIndex] // 前闭后开

slice := arr[:endIndex] // startIndex默认0

slice := arr[startIndex:] // endIndex默认len(arr)-1

slice := _slice[startIndex:endIndex] // 通过另一个切片初始化

切片的append()和copy()

如果想增加切片的容量,我们必须创建一个新的更大的切片并把原分片的内容都拷贝过来. 来自:www.runoob.com/go/go-slice…

package main

import "fmt"

func main() {
   var numbers []int
   printSlice(numbers)

   /* 允许追加空切片 */
   numbers = append(numbers, 0)
   printSlice(numbers)

   /* 向切片添加一个元素 */
   numbers = append(numbers, 1)
   printSlice(numbers)

   /* 同时添加多个元素 */
   numbers = append(numbers, 2,3,4)
   printSlice(numbers)

   /* 创建切片 numbers1 是之前切片的两倍容量*/
   numbers1 := make([]int, len(numbers), (cap(numbers))*2)

   /* 拷贝 numbers 的内容到 numbers1 */
   copy(numbers1,numbers)
   printSlice(numbers1)  
}

func printSlice(x []int){
   fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}

以上代码执行输出结果为:

len=0 cap=0 slice=[]
len=1 cap=1 slice=[0]
len=2 cap=2 slice=[0 1]
len=5 cap=6 slice=[0 1 2 3 4]
len=5 cap=12 slice=[0 1 2 3 4]

我自己试了一下:

package main
import "fmt"

func main() {
	var numbers = make([]int,10,10)
	fmt.Println(numbers)
	fmt.Println(len(numbers),cap(numbers))
	for i:=0;i<1;i++{
		numbers = append(numbers, i)
	}
	fmt.Println(numbers)
	fmt.Println(len(numbers),cap(numbers))
}

输出的是:

[0 0 0 0 0 0 0 0 0 0]
10 10
[0 0 0 0 0 0 0 0 0 0 0]
11 20

多试几次,其实切片的容量是自动增加的,每次都翻倍的增加。 所以这个教程说的不太对。

本来之前看过一次,发现忘得很快。这次一边看一边跟着敲,加深记忆。