GO语言学习系列六——GO的数组 array与切片 slice

Posted 星集

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GO语言学习系列六——GO的数组 array与切片 slice相关的知识,希望对你有一定的参考价值。

数组(array)

在GO语言中,数组是用于存储相同数据类型的集合,数组长度必须是一个常量表达式,且是一个非负数GO语言中的数组是一种值类型,下文会介绍

数组定义的格式

 
   
   
 
  1. var 数组名称 [数组长度]数组类型

  2. 例:

  3. var arr [3]int

输出为:

 
   
   
 
  1. [0 0 0]

在GO语言中,初始化数组时,给定了数组长度,但没给定数组下标的值, int类型默认值为 0, string类型默认为 空值,这是常用的两种类型

数组的赋值操作

 
   
   
 
  1. // 第一种赋值操作

  2. var arr = [3]int{1,2,3} //直接将值初始化,不同的类似初始化值不相同

  3. // 第二种赋值操作

  4. var arr [3]int    // 初始化数组变量

  5. arr[1] = 1        // 给数组的下标赋值

  6. // 第三种赋值操作

  7. var arr  = [3]string{1:"one",2:"two"}

  8. // 一般常用的就这三种,其它方式都是一些变相的操作,这里不做介绍

有必要说明一下:数组在初始中给定了数组的长度,用 len(arr)-1可以得到数组的长度,如果赋值时操出数组的最大长度,在编译的时候将会报错

先来个练习加深下前面所说的影响,将一个int型数组的值全部乘以2

 
   
   
 
  1. package main

  2. import "fmt"

  3. func main(){

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

  5.    for i, v := range arrs {

  6.        arrs[i] = v * 2

  7.        fmt.Printf("index is %d,value is %d \n", i, arrs[i])

  8.    }

  9. }

输出为

 
   
   
 
  1. index is 0,value is 2

  2. index is 1,value is 4

  3. index is 2,value is 6

  4. index is 3,value is 8

  5. index is 4,value is 10

数组的值类型

在GO语言中,数组的存储是一种值的类型,不像C等其它语言是指向首元素的指针,所以在创建数组也可以通过 new() 来创建一个指针数组 例:

 
   
   
 
  1. var arr1 = new([5]int)

  2. var arr2 [5]int

输出分别为

 
   
   
 
  1. &[0 0 0 0 0]

  2. [0 0 0 0 0]

&符号熟悉么,没错,他表明这是一个指针数组,在函数中传递时,不用将数组的值进行复制一遍

多维数组

在某种程度上面来说,多维数组其实就是将多个一维数组进行嵌套一种表达方式,例如: vararr1[3][5]int输出为 [[00000][00000][00000]]如果尝过其它语言编程的人一看就明白是怎么回事了

做个小题目:定义一个空的二维数组,将二维数组的值与索引一至

 
   
   
 
  1. package main

  2. import "fmt"

  3. func main{

  4. var arr_more [5][5]int

  5.    fmt.Println(arr_more)

  6.    for i, x := range arr_more {

  7.        for i1, _ := range x {

  8.            arr_more[i][i1] = i1

  9.        }

  10.    }

  11.    fmt.Println(arr_more)

  12. }

输出

 
   
   
 
  1. 初始化数组:

  2. [[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]

  3. 值与索引对应

  4. [[0 1 2 3 4] [0 1 2 3 4] [0 1 2 3 4] [0 1 2 3 4] [0 1 2 3 4]]

数组的处理还有很多别的形式,等着你在实际工作中的发现与总结

切片(slice)

切片是对数组一个连续片段的引用,它是一个引用类型,存储的是指针,所以在性能上比值数组更快,使用方法和数组基本类似,也可以通过索引进行访问, len()获得切片的长度, cap()获得切片最大的长度

切片声明格式

 
   
   
 
  1. var 声明变量 []变量类型

和声明数组非常相似,切片的声明是不需要指定数组长度,因为切片的长度是可变的(等会介绍)

一个切片在初始化之前默认为 nil,长度为 0一个相对完整的例子:

 
   
   
 
  1. package main

  2. import "fmt"

  3. func main{

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

  5.    var slice []int

  6.    fmt.Printf("初始化切片默认 %d\n", slice)

  7.    var slice1 []int = arr[:]

  8.    fmt.Printf("切片复制数组(简写) %d\n", slice1)

  9.    var slice2 []int = arr[0:2]

  10.    fmt.Printf("切片获得数组0-1的下标 %d\n", slice2)

  11.    var slice3 []int = arr[2:5]

  12.    fmt.Printf("切片获得数组2-4的下标 %d\n", slice3)

  13. }

输出

 
   
   
 
  1. 初始化切片默认 []

  2. 切片复制数组(简写) [1 2 3 4 5]

  3. 切片获得数组0-1的下标 [1 2]

  4. 切片获得数组2-4的下标 [3 4 5]

上面的例子介绍了切片的初始化和获得数组中某一个片段的值,当然还有一些其他用法比如 [:3], [3:]等等,切片的灵活性非常高,就看你需要什么数组的哪个片段

注意 绝对不要用指针指向 slice。切片本身已经是一个引用类型,所以它本身就是一个指针!!

用make()创建一个切片

当相关的数组还没有创建好的时候,我们可以用 make()函数来创建一个切片,同时创建好相关联的数组

 
   
   
 
  1. var slice []int = make([]type,len,cap)

  2. var 切片变量 []切片类型 = make([]数组类型,数组长度,最大长度) cap是可选参数

通过一个例子来说明make的使用

 
   
   
 
  1. package main

  2. import "fmt"

  3. func main() {

  4.    var slice1 []int = make([]int, 5)

  5.    for i := 0; i < len(slice1); i++ {

  6.        slice1[i] = 5 * i

  7.        fmt.Printf("Slice at %d is %d\n", i, slice1[i])

  8.    }

  9.    fmt.Printf("\nThe length of slice1 is %d\n", len(slice1))

  10.    fmt.Printf("The capacity of slice1 is %d\n", cap(slice1))

  11. }

输出

 
   
   
 
  1. Slice at 0 is 0  

  2. Slice at 1 is 5  

  3. Slice at 2 is 10  

  4. Slice at 3 is 15  

  5. Slice at 4 is 20

  6. The length of slice1 is 5  

  7. The capacity of slice1 is 5  

make()函数在初始化切片是经常被使用的方式,当然你要用简单的 varslice[]int=arr[:]也可以,看习惯

切片的复制与追加

通过 copy()append()来进行操作 一个例子:

 
   
   
 
  1. package main

  2. import "fmt"

  3. func main(){

  4. sl_from := []int{1, 2, 3}

  5.    sl_to := make([]int, 10)

  6.    n1 := copy(sl_to, sl_from)

  7.    fmt.Println(sl_to)

  8.    fmt.Printf("Copied %d elements\n", n1) // n == 3

  9.    sl3 := []int{1, 2, 3}

  10.    sl3 = append(sl3, 4, 5, 6)

  11.    fmt.Println(sl3)

  12. }

输出:

 
   
   
 
  1. [1 2 3 0 0 0 0 0 0 0]

  2. Copied 3 elements

  3. [1 2 3 4 5 6]

复制与增加需要注意的:

  1. 是将后面的元素或切片追加到前面

  2. 必须是相同的元素类型

  3. 如果上面的条件都满足,一般来说都会返回成功,除非内存耗尽了(无解)

小记:

当然切片还有更多的细节及处理方式,完整版最好还是去看官方提供的文档,本篇重点介绍了GO的数组与切片,下一篇将介绍GO的map类型

如果觉得文章能够对您有所帮助,可以关注我,你的支持会鼓励我不断分享更多更好的优质文章。



以上是关于GO语言学习系列六——GO的数组 array与切片 slice的主要内容,如果未能解决你的问题,请参考以下文章

Go 语言范围(Range)

GO语言切片Slice数组Array的比较;利用多维切片接受EXCEL内容的输出

Go语言中的数组与数组切片

Go语言系列之数组和切片

Go语言自学系列 | go语言切片的遍历

Go 的切片与数组