当前位置: 首页 > news >正文

【Go】Go语言中的数组基本语法与应用实战

在这里插入图片描述

✨✨ 欢迎大家来到景天科技苑✨✨

🎈🎈 养成好习惯,先赞后看哦~🎈🎈

🏆 作者简介:景天科技苑
🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。
🏆《博客》:Python全栈,Golang开发,PyQt5和Tkinter桌面开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,云原生K8S,linux,shell脚本等实操经验,网站搭建,数据库等分享。

所属的专栏:Go语言开发零基础到高阶实战
景天的主页:景天科技苑

在这里插入图片描述

文章目录

  • Go语言数组
    • 什么是数组
    • 数组的基本用法
      • 1. 数组的声明
      • 2. 数组几个特点:
      • 3. 数组的定义方式
      • 4. 初始化数组的几种方式
    • 数组是值类型
    • 数组排序
      • 算法:冒泡排序
    • 多维数组

Go语言数组

Go语言中的数组(Array)和切片(Slice)是处理数据的两种重要数据结构。
数组是一种相同数据类型、并且具有固定长度的序列,而切片则是对数组或另一个切片的一个连续片段的引用,提供了一种灵活且强大的方式来操作数据集合。

什么是数组

  • 一组数
    • 数组需要是相同类型的数据的集合
    • 数组是需要定义大小的
    • 数组一旦定义了大小是不可以改变的。

数组的基本用法

1. 数组的声明

数组和其他变量定义没什么区别,唯一的就是这个是一组数,需要给一个大小 [6]int [10]string
数组是一个相同类型数据的有序集合,通过下标来取出对应的数据

2. 数组几个特点:

1、长度必须是确定的,如果不确定,就不是数组,大小不可以改变
2、元素必须是相,同类型不能多个类型混合, [any也是类型,可以存放任意类型的数据]
3、数组的中的元素类型,可以是我们学的所有的类型,int、string、float、bool、array、slice、map

3. 数组的定义方式

数组的定义: [数组的大小size] 变量的类型 ,
我们定义了一组这个类型的数组集合,大小为size,最多可以保存size个数

定义了数组数据类型, 数组中的数据必须使用同一种数据类型,否则报错

package mainimport "fmt"func main() {//定义数组: [数组的大小size] 变量的类型//定义了数据类型,数组里面必须使用同一种数据类型//定义了数组长度,如果某个下标未赋值,会给出其数据类型的默认值var a = [5]int{1, 2, 3, 4, "5"}fmt.Println(a)}

在这里插入图片描述

数组赋值:
声明数组长度和数据类型

var a [5]int
// 给数组赋值,下标index,所有的数组下标都是从0开始的。
a[0] = 100
a[1] = 200
a[2] = 300
a[3] = 400
a[4] = 500打印数组
fmt.Println(a)通过下标方式获取数组某元素
fmt.Println(a[1])

在这里插入图片描述
在这里插入图片描述

获取数组长度和数组容量
数组中的常用方法 len()获取数组的长度 cap() 获取数组的容量
数组的容量在定义后就不能更改,而切片的容量在定义后可以更改。

fmt.Println("数组长度:", len(a))
fmt.Println("数组容量", cap(a))

在这里插入图片描述

修改数组的值,直接通过下标修改

a[2] = 3000
fmt.Println(a)
fmt.Println(a[2])

在这里插入图片描述

完整代码:

package mainimport "fmt"// 数组
// 数组和其他变量定义没什么区别,唯一的就是这个是一组数,需要给一个大小  [6]int   [10]string
// 数组是一个相同类型数据的==有序==集合,通过下标来取出对应的数据
// 数组几个特点:
// 1、长度必须是确定的,如果不确定,就不是数组,大小不可以改变
// 2、元素必须是相,同类型不能多个类型混合, [any也是类型,可以存放任意类型的数据]
// 3、数组的中的元素类型,可以是我们学的所有的类型,int、string、float、bool、array、slice、mapfunc main() {//数组本身也是一种数据类型//定义数组: [数组的大小size] 变量的类型//定义了数据类型,数组里面必须使用同一种数据类型//声明数组长度和数据类型var a [5]int// 给数组赋值,下标index,所有的数组下标都是从0开始的。//定义了数组长度,如果某个下标未赋值,会给出其数据类型的默认值a[0] = 100a[1] = 200a[2] = 300a[3] = 400a[4] = 500//打印数组fmt.Println(a)//取出数组中的某元素fmt.Println(a[1])//数组中的常用方法 len()获取数组的长度  cap() 获取数组的容量fmt.Println("数组长度:", len(a))fmt.Println("数组容量", cap(a))//修改数组的值a[2] = 3000fmt.Println(a)fmt.Println(a[2])}

4. 初始化数组的几种方式

1.在定义数组的时候就直接初始化,用大括号包裹数组的值

var arr1 = [5]int{1, 2, 3, 4, 5}
fmt.Println(arr1)

在这里插入图片描述

2.短变量快速初始化

arr2 := [3]int{1, 2, 3}
fmt.Println(arr2)

在这里插入图片描述

  1. 自动根据数组的长度来给 … 赋值,自动推导长度
    数据如果来自用户,我不知道用户给我多少个数据,数组
    … 代表数组的长度
    Go的编译器会自动根据数组的长度来给 … 赋值,自动推导长度
    注意点:这里的数组不是无限长的,也是固定的大小,大小取决于数组元素个数。
var arr3 = [...]int{1, 2, 3, 4, 5, 5, 6, 7, 8, 8, 8}
fmt.Println(len(arr3))
fmt.Println(arr3)

在这里插入图片描述

  1. 数组默认值,我只想给其中的某几个index位置赋值。
    {index:值}
var arr4 [10]int
arr4 = [10]int{1: 100, 5: 500}
fmt.Println(arr4) // [0 100 0 0 0 500 0 0 0 0]

给赋值的下标有值,没赋值的下标是默认值
在这里插入图片描述

完整代码:

package mainimport "fmt"func main() {// 在定义数组的时候就直接初始化,用大括号包裹数组的值var arr1 = [5]int{1, 2, 3, 4, 5}fmt.Println(arr1)//短变量快速初始化arr2 := [3]int{1, 2, 3}fmt.Println(arr2)// 比较特殊的点// 数据如果来自用户,我不知道用户给我多少个数据,数组// ... 代表数组的长度// Go的编译器会自动根据数组的长度来给 ... 赋值,自动推导长度// 注意点:这里的数组不是无限长的,也是固定的大小,大小取决于数组元素个数。//var arr3 = [...]int{1, 2, 3, 4, 5, 5, 6, 7, 8, 8, 8}arr3 := [...]int{1, 2, 3, 4, 5, 5, 6, 7, 8, 8, 8}fmt.Println(len(arr3))fmt.Println(arr3)// 数组默认值,我只想给其中的某几个index位置赋值。// {index:值}var arr4 [10]intarr4 = [10]int{1: 100, 5: 500}fmt.Println(arr4) // [0 100 0 0 0 500 0 0 0 0]
}遍历数组元素
遍历数组可以通过下标获取元素 arr[index]、使用for循环或者for-range结构。
直接通过下标获取元素 arr[index]使用for循环遍历:
for i := 0; i < len(arr); i++ {  fmt.Println(arr[i])  
}使用for-range遍历:
for index, value := range arr {  fmt.Printf("Index: %d, Value: %d\n", index, value)  
}

goland 快捷方式 数组.forr,来循环数组。
在这里插入图片描述

切片很多时候都使用for range
for 下标,下标对应的值 range 目标数组切片
就是将数组进行自动迭代。返回两个值 index、value
注意点,如果只接收一个值,这个时候返回的是数组的下标
注意点,如果只接收两个值,这个时候返回的是数组的下标和下标对应的值

package mainimport "fmt"/*
1、直接通过下标获取元素 arr[index]2、 0-len i++ 可以使用for循环来结合数组下标进行遍历3、for range:范围   (new)
*/
func main() {var arr1 = [5]int{1, 2, 3, 4, 5}fmt.Println(arr1[0])fmt.Println(arr1[1])fmt.Println(arr1[2])fmt.Println(arr1[3])fmt.Println(arr1[4])// 错误:index 5 out of bounds [0:5] 数组下标越界// 数组的长度只有5,你要取出6个元素,不可能取出//fmt.Println(arr1[5])fmt.Println("------------------")// 获取数组的长度  len()// 下标从0开始,不能<=for i := 0; i < len(arr1); i++ {fmt.Println(arr1[i])}fmt.Println("------------------")// goland 快捷方式 数组.forr,未来循环数组、切片很多时候都使用for    range// for 下标,下标对应的值  range 目标数组切片// 就是将数组进行自动迭代。返回两个值 index、value// 注意点,如果只接收一个值,这个时候返回的是数组的下标// 注意点,如果只接收两个值,这个时候返回的是数组的下标和下标对应的值// 如果我们只想要数组的值,index可以用_匿名变量来接收for _, value := range arr1 {fmt.Println(value)}}

在这里插入图片描述

数组是值类型

所有的赋值后的对象修改值后不影响原来的对象,赋值后的对象和原对象是互相独立的
验证值传递还是引用传递一个很好的方式就是:赋值后修改值,看是否影响原来的变量值,如果不影响就是值传递,影响了就是引用传递
在这里插入图片描述

package mainimport "fmt"// 数组是值类型: 所有的赋值后的对象修改值后不影响原来的对象。
func main() {//数组类型的样子 [size]typearr1 := [4]int{1, 2, 3, 4}arr2 := [5]string{"景天", "科技"}//字符串类型的值不写,默认是空串fmt.Println(arr1, "\n", arr2)fmt.Printf("%T\n", arr1) // [4]intfmt.Printf("%T\n", arr2) // [5]string// 数组的值传递和int等基本类型一致arr3 := arr1fmt.Println(arr1)fmt.Println(arr3)// 修改arr3观察arr1是否会变化arr3[0] = 12fmt.Println(arr1)fmt.Println(arr3) // 数组是值传递,拷贝一个新的内存空间
}

可见修改赋值后的变量值,不影响原来变量的值,得知数组是值传递
在这里插入图片描述

数组排序

数组的排序,一组数是乱序的,我们如何将它按照升序或者降序排列。

常见的排序算法:冒泡排序、插入排序、选择排序、希尔排序、堆排序、快速排序、归并排序、基数排序…
在这里插入图片描述

arr := [6]int{1,2,3,4,5,0}
// 升序 ASC  : 从小到大  0,1,2,3,4,5   A-Z    00:00-24:00
// 降序 DESC : 从大到小  5,4,3,2,1,0

数据结构:数组就是最简单的数据结构之一

算法:冒泡排序

package mainimport "fmt"// 冒泡:每次筛选出一个最大或者最小的数.
/*
index   0   1   2   3   4
value   12  99  79  48  55
*/
// 冒泡排序逻辑,两两比较,大的往后移或者前移。 大
// 第一轮 : 12 79 48 55 99 // 5
// 第二轮 : 12 48 55 79 99 // 4
// 第三轮 : 12 48 55 79 99 // 3 //
// 第四轮 : 12 48 55 79 99 //
// 第五轮 : 12 48 55 79 99// 代码实践
/*// 两个数判断,如果一个数大,则交换位置,大放到后面if arr[x] > arr[x+1] {arr[x], arr[x+1] = arr[x+1],arr[x]}// 多轮判断,for, 循环次数 【数组大小】
*/
func main() {arr := [...]int{12, 99, 79, 48, 55, 1, 110, 111, 23, 52, 354, 2, 3412, 3, 12, 31}fmt.Println("初始数组:", arr)// 冒泡排序// 1、多少轮for i := 1; i < len(arr); i++ {// 2、筛选出来最大数字以后,我们下次不需要将它再计算了for j := 0; j < len(arr)-i; j++ {// 比较 // 改变升降序只需要改变符号即可if arr[j] < arr[j+1] {arr[j], arr[j+1] = arr[j+1], arr[j]}}fmt.Println("第", i, "交换:", arr)}}

我们看到在第12次交换后,其实已经排序好了,但是循环还在继续
在这里插入图片描述

为了节省计算机资源,我们希望排序完之后不再继续进行比较了,怎么实现呢?
看如下代码
临时变量检测法

package mainimport "fmt"func main() {a := [...]int{21, 72, 564, 27, -12, 0, 32, 999, 54, 81}//打印最初数组fmt.Println("最初数组", a)//冒泡排序for i := 1; i < len(a); i++ {//交换之前先将a赋值给一个临时变量。当交换结束,a与临时变量相同,表示已经排序完成temp := a//筛选出来最大数字后就不需要再次进行比较了for j := 0; j < len(a)-i; j++ {if a[j] > a[j+1] {a[j], a[j+1] = a[j+1], a[j]}}//排序好后结束循环//交换完成判断,a是否发生了变化,如果没变表示排序结束,结束循环if a == temp {break}fmt.Println("第", i, "次交换", a)}fmt.Println("排序后的数组:", a)}

在这里插入图片描述

多维数组

一维数组: 线性的,一组数

二维数组: 表格性的,数组套数组

三维数组: 立体空间性的,数组套数组套数组

xxxx维数组:xxx,数组套数组套数组…

在这里插入图片描述

在这里插入图片描述

用法代码展示

package mainimport "fmt"func main() {// 定义一个多维数组  二维arr := [3][4]int{{0, 1, 2, 3},   // arr[0]  //数组{4, 5, 6, 7},   // arr[1]{8, 9, 10, 11}, // arr[2]}// 二维数组,一维数组存放的是一个数组fmt.Println(arr[0])// 要获取这个二维数组中的某个值,找到对应一维数组的坐标,arr[0] 当做一个整体fmt.Println(arr[0][1])fmt.Println("------------------")// 如何遍历二维数组for i := 0; i < len(arr); i++ {for j := 0; j < len(arr[i]); j++ {fmt.Println(arr[i][j])}}// for rangefor i, v := range arr {fmt.Println(i, v)}
}

在这里插入图片描述

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 写作神器!推荐4款AI免费的写论文的文献网站
  • redisController工具类
  • 动态内存管理之malloc,free,calloc和realloc函数
  • Flip动画的实现示例demo
  • mysql的zip解压缩版安装
  • 常见的限流算法
  • hnust 湖科大 毕业实习常见问题30问(2021 年7月,V0.9)
  • django orm增删改查操作
  • 从零到一:构建你的第一个AI项目(实战教程)
  • 【算法】差分思想:强大的算法技巧
  • Parallels Desktop 20 for Mac中文版发布了?会哪些新功能
  • uniapp 做一个查看图片的组件,图片可缩放移动
  • 基于C++的成绩管理系统
  • 828华为云征文 | 使用Flexus云服务器X实例部署GLPI资产管理系统
  • 基于python+django+vue的外卖管理系统
  • 「面试题」如何实现一个圣杯布局?
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • CSS 专业技巧
  • ES2017异步函数现已正式可用
  • github从入门到放弃(1)
  • HTML5新特性总结
  • input的行数自动增减
  • laravel 用artisan创建自己的模板
  • Linux链接文件
  • python3 使用 asyncio 代替线程
  • Spark VS Hadoop:两大大数据分析系统深度解读
  • 关于使用markdown的方法(引自CSDN教程)
  • 前端面试之CSS3新特性
  • 说说动画卡顿的解决方案
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • 数据可视化之下发图实践
  • ‌移动管家手机智能控制汽车系统
  • #Linux杂记--将Python3的源码编译为.so文件方法与Linux环境下的交叉编译方法
  • #NOIP 2014#day.2 T1 无限网络发射器选址
  • #我与Java虚拟机的故事#连载15:完整阅读的第一本技术书籍
  • (20050108)又读《平凡的世界》
  • (9)YOLO-Pose:使用对象关键点相似性损失增强多人姿态估计的增强版YOLO
  • (pycharm)安装python库函数Matplotlib步骤
  • (八)Docker网络跨主机通讯vxlan和vlan
  • (搬运以学习)flask 上下文的实现
  • (附源码)springboot 智能停车场系统 毕业设计065415
  • (附源码)springboot美食分享系统 毕业设计 612231
  • (附源码)springboot学生选课系统 毕业设计 612555
  • (三)SvelteKit教程:layout 文件
  • (十五)Flask覆写wsgi_app函数实现自定义中间件
  • (数据结构)顺序表的定义
  • (四)c52学习之旅-流水LED灯
  • (转)Windows2003安全设置/维护
  • (转)大型网站的系统架构
  • .gitignore文件使用
  • .Mobi域名介绍
  • .NET C#版本和.NET版本以及VS版本的对应关系
  • .NET Core中如何集成RabbitMQ
  • .NET 使用 JustAssembly 比较两个不同版本程序集的 API 变化
  • .NET 通过系统影子账户实现权限维持