[go学习笔记.第七章.数组和切片] 3.切片的基本介绍和入门,切片在内存中的布局分析

1.为什么需要切片

先看一个需求:

        需要用一个数组保存学生的成绩,但是学生的个数是不确定的,请问怎么办?

 解决方案:

        使用切片

2.切片的基本介绍

(1).切片的英文名称是slice

(2).切片是数组的一个引用,因此切片是引用类型,在进行传递时,遵守引用传递机制

(3).切片的使用和数组类似,遍历切片,访问切片的元素和求切片的长度(len(slice))都是一样的

(4).切片的长度是可变的,因此切片是一个可以动态变化数组

(5).切片定义的基本语法:

        var 切片名 []类型

        比如: var a []int 

package main

import (
	"fmt"
)

func main() {
	//演示切片的基本使用
	var intArr  [5]int = [...]int{1,2,3,4,5}
	//声明/定义
	//slice := intArr[1:3]
	//1.slice 就是切片名
	//2.intArr[1:3] 表示slice引用到intArr这个数组
	//3.引用intArr这个数组的起始下标为1,最后的下标为3(但不包含3)
	slice := intArr[1:3]
	fmt.Println("intArr = ", intArr)	//[1 2 3 4 5]
	fmt.Println("slice 的元素是 = ", intArr)	//[2 3]
	fmt.Println("slice 的元素个数是= ", len(slice))	// 2
	fmt.Println("slice 的容量 = ", cap(slice))	// 切片的容量是可以动态变化的

	fmt.Printf("intArr[1]的地址: %p\n", &intArr[1])	// intArr[1]的地址: 0xc00000a39
	fmt.Printf("slice[0]的地址: %p, slice[0]的值: %v,\n", &slice[0], slice[0])	//slice[0]的地址: 0xc00000a398, slice[0]的值: 2
	slice[1] = 33
	fmt.Println("intArr = ", intArr)	//[1 33 3 4 5]
	fmt.Println("slice 的元素是 = ", intArr)	//[2 33]
}

  

  3.切片在内存中的形式

基本介绍

        为了深刻理解切片,画图分析切片在内存中是如何布局的

package main

import (
	"fmt"
)

func main() {
	//演示切片的基本使用
	var intArr  [5]int = [...]int{1,2,3,4,5}
	//声明/定义
	//slice := intArr[1:3]
	//1.slice 就是切片名
	//2.intArr[1:3] 表示slice引用到intArr这个数组
	//3.引用intArr这个数组的起始下标为1,最后的下标为3(但不包含3)
	slice := intArr[1:3]
	fmt.Println("intArr = ", intArr)	//[1 2 3 4 5]
	fmt.Println("slice 的元素是 = ", intArr)	//[2 3]
	fmt.Println("slice 的元素个数是= ", len(slice))	// 2
	fmt.Println("slice 的容量 = ", cap(slice))	// 切片的容量是可以动态变化的

	fmt.Printf("intArr[1]的地址: %p\n", &intArr[1])	// intArr[1]的地址: 0xc00000a39
	fmt.Printf("slice[0]的地址: %p, slice[0]的值: %v,\n", &slice[0], slice[0])	//slice[0]的地址: 0xc00000a398, slice[0]的值: 2
	slice[1] = 33
	fmt.Println("intArr = ", intArr)	//[1 33 3 4 5]
	fmt.Println("slice 的元素是 = ", intArr)	//[2 33]
}

slice底层实现的原理是通过数组来实现的,Slice是由三个部分组成的:指针、长度和容量:

  • 指针指向底层数组的第一个元素
  • 长度表示slice当前包含的元素数量
  • 容量表示底层数组从指针开始可访问的元素数量

当创建一个slice时,Go会自动创建一个底层数组,并将指针指向该数组的首个元素,同时将长度和容量初始化为相同的值。当slice添加元素时,如果元素的数量超过了slice的容量,Go会自动创建一个新的底层数组,并将原有元素复制到新的数组中。这样可以保证slice的连续性。当slice被传递给函数时,函数接收的是slice的副本,但是该副本会共享底层数组。因此,通过函数修改slice中的元素会影响到原有的slice和底层数组.

总结起来,slice底层实现的原理是通过指针、长度和容量来引用和管理底层数组,保证了slice的连续性和共享性,这种设计使得slice在性能和灵活性上都具有优势 

 [上一节][go学习笔记.第七章.数组和切片] 2.数组的遍历,注意事项和细节以及数组的应用实例

 [下一节][go学习笔记.第七章.数组和切片] 4.切片的三种使用方式以及注意事项和使用细节 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值