• 09【保姆级】-GO语言的数组和切片


    之前我学过C、Java、Python语言时总结的经验:

    1. 先建立整体框架,然后再去抠细节。
    2. 先Know how,然后know why。
    3. 先做出来,然后再去一点点研究,才会事半功倍。
    4. 适当的囫囵吞枣。因为死抠某个知识点很浪费时间的。
    5. 对于GO语言,切记遵守语法格式规则。(例如python语言、例如SpringBoot框架等)
      解释:某些知识点,就是很难了解,那么先做出来,然后继续向前学习,可能在某个时间点我们就会恍然大悟。

    一、数组

    1.1 数组定义

    数组可以存放多个同一类型数据。数组也是一种数据类型,在 Go 中,数组是值类型。

    初始化的四种方式:

    var arr01 [3]int = [3]int{1, 2, 3}
    var arr02 = [3]int{1, 2, 3}
    var arr03 = [...]int{1, 2, 3}
    var arr04 = [...]int{1: 111, 0: 001, 2: 222}
    fmt.Println("arr04=", arr04) // arr04= [1 111 222]
    // 设置排序顺序
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    数组的首地址 也就是 数组第一个元素的地址。第二个元素的地址是:首地址+数组类型的占用的字节数。

    var arr [5]float64
    fmt.Printf("首地址是:%p,首元素地址是:%p,第二个元素的地址是:%p", &arr, &arr[0], &arr[1])
    // 首地址是:0xc042076030,首元素地址是:0xc042076030,第二个元素的地址是:0xc042076038
    
    • 1
    • 2
    • 3

    1.2 数组的使用

    func main() {
    	var arr [5]float64
    	arr[0] = 1.2
    	arr[1] = 2.2
    	arr[2] = 21.2
    	arr[3] = 3.2
    	arr[4] = 4.2
    	num := 0.0
    	for i := 0; i < len(arr); i++ {
    		num += arr[i]
    	}
    	fmt.Println("num=", num)  //n um= 32
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    1.3 数组的遍历

    方式一常规方式:如上述章节方式

    方式二:for-range结构遍历:用来遍历访问数组的元素

    for index,value :=range array01{
    
    }
    
    • 1
    • 2
    • 3
    1. 第一个返回值 index是数组的下标
    2. 第二个value是在该下标位置的值
    3. 他们都是仅在for循环内部可见的局部变量
    4. 遍历数组元素的时候,如果不想使用下标index,可以直接把下标index标为下划线_
    5. index和value 的名称不是固定的,即程序员可以自行指定,一般命名为index 和value
    arr := [...]string{"张三", "lisi", "王五", "赵六"}
    for i, s := range arr {
    	fmt.Println("元素索引是:", i, "元素是:", s)
    }
    元素索引是: 0 元素是: 张三
    元素索引是: 1 元素是: lisi
    元素索引是: 2 元素是: 王五
    元素索引是: 3 元素是: 赵六
    
    ----
    
    arr := [...]string{"张三", "lisi", "王五", "赵六"}
    for _, s := range arr {
    	fmt.Println("元素是:", s)
    }
    元素是: 张三
    元素是: lisi
    元素是: 王五
    元素是: 赵六
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    1. 数组的下标是从0开始的。
    2. 数组下标必须在指定范围内使用,否则报 panic: 数组越界,比如var arr[5]int 则有效下标为 0-4
    3. Go的数组属值类型,在默认情况下是值传递, 因此会进行值拷贝。数组间不会相互影响
    4. 如想在其它函数中,去修改原来的数组,可以使用引用传递(指针方式)[先体验下,画示意图]
    ---值传递: 在test栈中会赋值arr的数据
    func main() {
    	arr := [...]string{"11", "22", "33", "444"}
    
    	testArr(arr)
    	fmt.Println(arr) //  [11 22 33 444]
    }
    
    func testArr(arr [4]string) {
    	arr[0] = "9999"
    }
    
    --- 地址传递:在test栈中会直接指向arr数组的数据。
    // 所以可以改变数组中的元素
    func main() {
    	arr := [...]string{"11", "22", "33", "444"}
    
    	testArr(&arr)
    	fmt.Println(arr)  //  [9999 22 33 444]
    }
    
    func testArr(arr *[4]string) {
    	arr[0] = "9999"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    1.4 数组的应用案例

    遍历数组从A加到Z,然后遍历输出:

    func main() {
    
    	var arr [26]byte
    	for i := 0; i < 26; i++ {
    		arr[i] = 'A' + byte(i)
    	}
    	fmt.Println(arr)
    	// [65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90]
    	for _, v := range arr {
    		fmt.Printf("%c ", v)
    	}
    	//  A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    二、切片

    个数不确定时,可以使用切片。

    2.1 切片的介绍

    1. 切片的英文是 slice
    2. 切片是数组的一个引用,因此切片是引用类型,在进行传递时,遵守引用传递的机制
    3. 切片的使用和数组类似,遍历切片、访问切片的元素和求切片长度 len(slice)都一样
    4. 切片的长度是可以变化的,因此切片是一个可以动态变化数组。
    5. 切片定义的基本语法
      var 切片名[类型]
      比如: var a I int

    2.2 切片的原理

    切片是有三部分组成:

    • 指向数组的地址
    • 指向数组的长度
    • 切片的容量长度
      在这里插入图片描述

    2.3 切片的三种使用

    方式一:创建好的数组,进行切片

    func main() {
    
    	var arr [26]byte
    	for i := 0; i < 26; i++ {
    		arr[i] = 'A' + byte(i)
    	}
    
    	for _, v := range arr {
    		fmt.Printf("%c ", v)
    	}
    	fmt.Println()
    	//  A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
    
    	Myslice := arr[1:10]
    
    	fmt.Printf("遍历Myslice切片元素: %c \n", Myslice) //slice: [66 67 68 69 70 71 72 73 74]
    	fmt.Printf("切片的第一个元素:%p, 对应数组的地址是:%p", &Myslice[0], &arr[1])
    	// 切片的第一个元素:0xc0420580a1, 对应数组的地址是:0xc0420580a1
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    内置的make来创作切片:

  • 相关阅读:
    从0到0.01入门React | 010.精选 React 面试题
    如何迈向IPv6之IPv6过渡技术-尚文网络奎哥
    蔚来的长期主义,全靠特斯拉衬托
    maya安装时,更改注册登录方式技巧
    鼠标监视 | 拖拽方块 | Vue
    高性能可编程射频移相器介绍
    聚美优品根据ID取商品详情 API
    解决VSCODE 终端中显示中文乱码的问题
    【typeof instanceof Object.prototype.toString constructor区别】
    (十)死信队列
  • 原文地址:https://blog.csdn.net/weixin_43989347/article/details/134514651