Go:数组与切片

ゝ一世哀愁。 2023-02-12 05:45 110阅读 0赞

文章目录

  • 一、数组
    • 1.1 数组的定义
    • 1.2 数组的初始化
    • 1.3 数组的遍历
    • 1.4 数组使用的注意事项和细节
  • 二、切片
    • 2.1 切片的定义
    • 2.2 切片的使用
    • 2.3 切片的遍历
    • 2.4 切片使用的注意事项和细节
    • 2.5 string 和 slice

一、数组

1.1 数组的定义

定义:var 数组名 [数组大小]数据类型

案例:

  1. func main() {
  2. var arr [3]int
  3. fmt.Println(arr)
  4. fmt.Printf("arr的地址是=%p,arr[0]的地址是=%p", &arr,&arr[0])
  5. }

数组在内存布局:
在这里插入图片描述

  • 数组的地址可以通过数组名来获取&arr
  • 数组的第一个元素的地址,就是数组的首地址
  • 数组的各个元素的地址间隔是依据数组的类型决定,比如int64 -> 8 int32->4

1.2 数组的初始化

  1. func main() {
  2. var arr1 [3]int = [3]int{ 1, 2, 3}
  3. fmt.Println(arr1)//[1 2 3]
  4. var arr2 = [3]int{ 4, 5, 6}
  5. fmt.Println(arr2)//[4 5 6]
  6. var arr3 = [...]int{ 1, 2, 3}
  7. fmt.Println(arr3)//[1 2 3]
  8. var arr4 = [...]int{ 1:1, 0:2, 2:3}
  9. fmt.Println(arr4)//[2 1 3]
  10. arr5 :=[...]int{ 1,2,3}
  11. fmt.Println(arr5)//[1 2 3]
  12. }

1.3 数组的遍历

①常规

  1. func main() {
  2. arr := [3]int{ 1, 2, 3}
  3. for i := 0; i < len(arr); i++ {
  4. fmt.Printf(" %d", arr[i])
  5. }
  6. }

②for-range

语法:

  1. for index, value := range arr {
  2. ...
  3. }

说明:

  1. 第一个index是数组的下标
  2. 第二个value即对应的值
  3. 若不需要index,可以用_替换

案例:

  1. func main() {
  2. arr := [3]int{ 4, 5, 6}
  3. for i, v := range arr {
  4. fmt.Printf("arr[%d]=%d ", i, v) //arr[0]=4 arr[1]=5 arr[2]=6
  5. }
  6. }

1.4 数组使用的注意事项和细节

  1. 数组是多个相同类型数据的组合,一个数组一旦声明、定义了,其长度是固定的, 不能动态变化
  2. var arr []int这时arr就是一个slice切片
  3. 数组创建后,如果没有赋值,会使用默认值。数组类型默认值:0,字符串类型默认值:””,bool默认值:0
  4. 数组下标必须在指定范围内使用,否则报panic:数组越界
  5. Go 的数组属值类型, 在默认情况下是值传递, 因此会进行值拷贝。若要修改原来的数组,可以使用引用传递(指针方式)

二、切片

2.1 切片的定义

切片(slice)是数组的一个引用,因此切片是引用类型,在进行传递时,遵守引用传递的机制。切片的使用和数组类似,切片的长度是可以变化的,因此切片是一个可以动态变化数组。

定义:var 切片名 []类型

  1. func main() {
  2. arr := [...]int{ 1, 2, 3, 4, 5}
  3. slice := arr[1:3]
  4. fmt.Printf("slice的类型:%T\n", slice)//slice的类型为[]int
  5. fmt.Println("slice的元素:", slice)//slice的元素: [2 3]
  6. fmt.Println("slice的元素个数:", len(slice))//slice的元素个数: 2
  7. fmt.Println("slice的容量:", cap(slice))//slice的容量: 4
  8. }

切片在内存布局:

可以看出,切片是一个引用类型,指向了某个数组。
在这里插入图片描述

2.2 切片的使用

①定义一个切片,然后让切片去引用一个已经创建好的数组

  1. func main() {
  2. arr := [...]int{ 1, 2, 3, 4, 5}
  3. slice := arr[1:3]
  4. fmt.Println("slice的元素:", slice)//slice的元素: [2 3]
  5. }

②通过make 来创建切片

基本语法:var 切片名 []type = make([]type, len, [cap])

参数说明:
type: 就是数据类型
len: 大小
cap :指定切片容量,可选, 如果你分配了cap,则要求cap>=len

案例:

  1. func main() {
  2. slice := make([]int, 5, 10)
  3. slice[0] = 1
  4. slice[1] = 2
  5. fmt.Println(slice)//[1 2 0 0 0]
  6. }

③直接指定具体数组

  1. func main() {
  2. slice := []int{ 1, 2, 3}
  3. fmt.Println(slice) //[1 2 3]
  4. }

2.3 切片的遍历

①常规

  1. func main() {
  2. arr := [...]int{ 1, 2, 3, 4, 5}
  3. slice := arr[1:3]
  4. for i := 0; i < len(slice); i++ {
  5. fmt.Printf("%d ", slice[i]) //2 3
  6. }
  7. }

②for-range

  1. func main() {
  2. arr := [...]int{ 1, 2, 3, 4, 5}
  3. slice := arr[1:3]
  4. for _, v := range slice {
  5. fmt.Printf("%d ", v)//2 3
  6. }
  7. }

2.4 切片使用的注意事项和细节

  1. 切片初始化时,仍然不能越界。范围在[0-len(arr)]之间,但是可以动态增长
    var slice = arr[0:end] 可以简写 var slice = arr[:end]
    var slice = arr[start:len(arr)] 可以简写: var slice = arr[start:]
    var slice = arr[0:len(arr)] 可以简写: var slice = arr[:]
  2. append内置函数,可以对切片进行动态追加(对数组进行动态扩容)

    func main() {

    1. slice := make([]int, 2, 2)
    2. slice[0] = 1
    3. slice[1] = 2
    4. slice = append(slice, 3, 4)
    5. fmt.Println(slice) //[1 2 3 4]

    }

  3. 切片是引用类型,所以在传递时,遵守引用传递机制

    func main() {

    1. var slice []int
    2. arr := [...]int{ 1, 2, 3}
    3. slice = arr[:]
    4. slice2 := slice
    5. slice2[0] = 4
    6. fmt.Println(arr)
    7. fmt.Println(slice)
    8. fmt.Println(slice2)

    }

2.5 string 和 slice

string底层是一个byte数组,因此string也可以进行切片处理

  1. func main() {
  2. str := "Hello Go"
  3. slice := str[:3]
  4. fmt.Println(slice)//Hel
  5. }

string是不可变的,不能通过str[0] = 'z'方式来修改字符串。可以先将string转为[]byte[]rune进行修改。

  1. func main() {
  2. str := "Hello Go"
  3. arr := []byte(str)
  4. arr[0] = 'F'
  5. str = string(arr)
  6. fmt.Println(str) //Fello Go
  7. arr2 := []rune(str)
  8. arr2[0] = 'C'
  9. str = string(arr2)
  10. fmt.Println(str) //Cello Go
  11. }

发表评论

表情:
评论列表 (有 0 条评论,110人围观)

还没有评论,来说两句吧...

相关阅读

    相关 go语言数组切片

    go数组操作灵活多变,借此机会复习一下这部分内容吧! 数组:长度固定,不能修改长度,长度通过内置函数len(array)获取。数组是值类型。 切片:动态数组,长度不固定

    相关 go 切片

    1、go语言中切片英文是 slice,跟我们其它语言的数组有一点相似,其实,go切片(就是一个动态的数组),切片是数组的一个引用,因此切片是引用类型,在进行传递时,遵守引用类