第七章 Golang数组和切片

简介: 第七章 Golang数组和切片

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

1.数组是多个相同类型数据的结合,一个数组一旦声明/定义了,其长度是固定的,不能动态变化。

2.var arr []int 这时arr就是一个slice切片,切片后面专门讲解。

3. 数组中的元素可以是任何数据类型,包括值类型和引用类型,但是不能混用。

4. 数组创建后,如果没有赋值,有默认值(零值)

数值类型数组:默认值为0

字符串数组:默认值为“”

bool数组:默认值为false

5. 使用数组的步骤 a.声明数组并开辟空间 b.给数组各个元素赋值(默认零值)c.使用数组

6. 数组的下标是从0开始的。

7. 数组下班必须在指定范围内使用,否则报panic:数组越界,比如var arr [5]int 则有效下表为0-4

8. Go的数组属值类型:在默认情况下是值传递,因此会进行拷贝。数组间不会相互影响

9. 如想在其他函数中,去修改原来的数组,可以使用应用传递(指针方式)

10.长度是数组类型的一部分,在传递函数参数时 需要考虑数组的长度,看下面案例

要求:生成五个数,并将其反转打印

// 思路 1.生成五个数,rand.Intn()函数  2.当我们得到随机数后,就放到一个数组 int数组 3.反转打印,交换的次数是len/2,倒数第一个和第一个元素交换,倒数第二个和第二个交换
var intArr3 [5]int
len := len(intArr3)
rand.Seed(time.Now().UnixNano())
for i := 0;i<len;i++ {
  intArr3[i] = rand.Intn(100) 
}
fmt.Println("交换前=",intArr3)
temp := 0
for i:=0;i<len/2;i++{
  temp = intArr3[len-1-i]
  intArr3[len-1-i] = intArr3[i]
  intArr3[i] = temp
}
fmt.Println("交换后=",intArr3)

为什么需要切片

先来看一个需求,我们需要一个数组用于保存学生的成绩,但是学生的个数是不确定的,请问怎么办:解决方案使用**切片**

切片的基本介绍

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

切片快速入门

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

切片在内存中形式

基本介绍

为了让大家更加深入的理解切片,我们画图分析一下切片在内存中是如何布局的,这是一个非常重要的知识点

画出前面的内存分布图

对上面的分析总结

1.slice的确是一个引用类型

2.slice 从底层来说,其实就是一个数据结构(struct结构体)

type slice struct{
ptr *[2]int
len int
cap int
}

切片的使用

方式一:定义一个切片,然后让切片去引用一个定义好的数组,比如之前的案例就是这样的。

方式二:通过make来创建切片

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

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

方式三:定义一个切片,直接就指定具体数组,使用原理类似make的方式

var strSlice []string = []string{"tom","jack","mary"}
fmt.Println("strSlice=",strSlice)
fmt.Println("strSlice size =",len(strSlice))
fmt.Println("strSlice cap =",cap(strSlice))

方式1和方式2的区别

方式1是直接引用数组,这个数组是事先存在的,程序员是可见的。方式2是通过make来创建切片,make也会创建一个数组,是由切片在底层进行维护,程序员是看不见的。

切片的遍历

切片的遍历和数组一样,也有两种方式

package main
import (
  "fmt"
)
func main(){
  // 使用常规的for循环遍历切片
  var arr [5]int = [...]int{10,20,30,40,50}
  slice  := arr[1:4] // 20,30,40
  for i := 0;i<len(slice);i++{
      fmt.Printf("slice[%v]=%v",i,slice[i])
  }
    // 使用for---range方式遍历切片
    for i,v := range slice{
      fmt.Printf("i=%v v=%v \n",i,v)
    }
}

切片注意事项和细节说明

用append内置函数,可以对切片进行动态追加

切片append操作的底层原理分析

  1. 切片append操作的本质就是对数组扩容
  2. go底层会创建一下新的数组newArr(安装扩容后大小)
  3. 将slice原来包含的元素拷贝到新的数组newArr
  4. slice重新引入到newArr
  5. 注意newArr是在底层来维护的,程序员不可见
  6. 切片是引用类型,所以在传递时,遵循引用传递机制。

切片的拷贝操作

切片使用copy内置函数完成拷贝,举例说明

func main(){
   var a []int = []int {1,2,3,4,5}
   var slice = make([]int,10)
   fmt.Println(slice)
   copy(slice,a)
   fmt.Println(slice)
}

string和slice

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

2.string和切片在内存的形式,以“abcd”画出内存示意图

3.string是不可变的,也就是说不能通过str[0]=‘z’方式来修改字符串

4. 如果需要修改字符串,可以先将string->[]byte/或者 []rune->修改->重写转成string.

切片生成斐波那契数列

func fbn(n int) ([]uint64){
  // 声明一个切片,切片大小n
  fbnSlice := make([]uint64,n)
  // 第一个数和第二个数的斐波那契 为1
  fbnSlice[0] = 1
  fbnSlice[1] = 1
  // 进行for循环来存放斐波那契的数列
  for i := 2;i<n;i++{
    fbnSlice[i] = fbnSlice[i-1] + fbnSlice[i-2]
  }
  return fbnSlice
}

感谢大家观看,我们下次见

目录
相关文章
|
12天前
|
Go 索引
Golang深入浅出之-切片(Slices)入门:创建、操作与扩容机制
【4月更文挑战第20天】Go语言中的切片是动态数组,提供灵活的操作和自动扩容。本文介绍了切片的创建(通过`make()`、数组创建和切片字面量)、基本操作(索引访问、切片、赋值追加和遍历)以及扩容机制(首次和后续扩容策略)。此外,还强调了切片与底层数组的关系、切片越界问题、`append()`的使用以及理解切片的关键点,帮助提升Go编程效率和代码质量。
28 0
|
4月前
|
Go C++ Java
C/C++每日一练(20230408) 删除无效括号、合并K个升序链表、四数之和
C/C++每日一练(20230408) 删除无效括号、合并K个升序链表、四数之和
33 0
C/C++每日一练(20230408) 删除无效括号、合并K个升序链表、四数之和
|
4月前
|
Go
Golang切片copy踩坑
Golang切片copy踩坑
26 0
|
7月前
|
存储 Java Go
Golang 语言中数组和切片的区别是什么?
Golang 语言中数组和切片的区别是什么?
32 0
|
7月前
|
存储 大数据 Go
100天精通Golang(基础入门篇)——第11天:深入解析Go语言中的切片(Slice)及常用函数应用
100天精通Golang(基础入门篇)——第11天:深入解析Go语言中的切片(Slice)及常用函数应用
70 0
|
10月前
|
算法 中间件 程序员
golang中的异常和切片
golang中的异常和切片
|
10月前
|
JavaScript 前端开发 Go
正确使用 Golang 循环创建新切片的方式
正确使用 Golang 循环创建新切片的方式
|
12月前
|
Go
Golang中的数组和切片
Golang中的数组和切片
70 0
|
Java Linux Go
知识分享之Golang——Golang中切片的一些增加、删除、添加、遍历删除
知识分享之Golang篇是我在日常使用Golang时学习到的各种各样的知识的记录,将其整理出来以文章的形式分享给大家,来进行共同学习。欢迎大家进行持续关注。 知识分享系列目前包含Java、Golang、Linux、Docker等等。
251 0
知识分享之Golang——Golang中切片的一些增加、删除、添加、遍历删除
|
9小时前
|
缓存 测试技术 持续交付
Golang深入浅出之-Go语言中的持续集成与持续部署(CI/CD)
【5月更文挑战第5天】本文介绍了Go语言项目中的CI/CD实践,包括持续集成与持续部署的基础知识,常见问题及解决策略。测试覆盖不足、版本不一致和构建时间过长是主要问题,可通过全面测试、统一依赖管理和利用缓存优化。文中还提供了使用GitHub Actions进行自动化测试和部署的示例,强调了持续优化CI/CD流程以适应项目需求的重要性。
15 1