数组是指一系列同一类型数据的集合。数组中包含的每个数据被称为数组元素(element),这种类型可以是任意的原始类型,比如 int、string 等,也可以是用户自定义的类型
一个数组包含的元素个数被称为数组的长度。在 Golang 中数组是一个长度固定的数据类型,数组的长度是类型的一部分,也就是说 [5]int 和 [10]int 是两个不同的类型。Golang 中数组的另一个特点是占用内存的连续性,也就是说数组中的元素是被分配到连续的内存地址中的,因而索引数组元素的速度非常快。

Golang 数组的特点

我们可以把 Golang 数组的特征归纳为以下三点:

  • 固定长度:这意味着数组不可增长、不可缩减。想要扩展数组,只能创建新数组,将原数组的元素复制到新数组。
  • 内存连续:这意味可以在缓存中保留的时间更长,搜索速度更快,是一种非常高效的数据结构,同时还意味着可以通过数值的方式(arr[index])索引数组中的元素。
  • 固定类型:固定类型意味着限制了每个数组元素可以存放什么样的数据,以及每个元素可以存放多少字节的数据。

数组是个固定长度的数据类型,其长度和存储元素的数据类型都在声明数组时确定,并且不能更改。如果需要存储更多的元素,必须先创建一个更长的数组,然后把原来数组里的数据复制到新数组中。
数组占用的内存是连续分配的,比如我们创建一个包含 5 个整数元素的数组:

var arr [5]int

数组的声明与初始化

声明数组声明数组时需要指定数组的长度和数组中元素的类型,比如声明一个包含 5 个元素,类型为 int 的数组:

var arr1 [5]int

这里强调一点,数组的类型是包含数组长度的,因此 [5]int 和 [10]int 是两个不同类型的数组。
在 Go 语言中声明变量时,总会使用对应类型的零值来初始化变量,数组也不例外。当声明数组变量时,数组内的每个元素被初始化为对应类型的零值。比如变量 arr1,它的 5 个元素都被初始化成了 int 类型的零值 0。使用 fmt.Println(arr1) 可以看到数组中元素的值:

package mainimport ("fmt"
)func main() {arr := make([]int, 5)arr[0] = 1fmt.Println("hello") // 输出[ 1 0 0 0 0]fmt.Println(arr)var a [5]stringa[0] = "a"fmt.Println(a)    // 输出 [a    ]
}

使用字面量初始化数组我们可以通过字面量在声明数组的同时快速的初始化数组:

arr2 := [5]int{10,20,30,40,50}

对于这种情况,还可以使用 … 代替数组的长度,让编译器根据实际的元素个数自行推断数组的长度:

arr3 := […]int{10,20,30,40,50}

如果设置了数组的长度,还可以通过指定下标的方式初始化部分元素:

// 用具体值初始化索引为 1 和 3 的元素
arr4 := [5]int{1:20,3:40}

访问与修改数组元素

和其它类 C 语言一样,Go 语言数组通过数组下标(索引位置)来读取或者修改数组元素。下标(索引)从 0 开始,第一个元素的索引为 0,第二个索引为 1,依次类推。元素的数目(数组长度)必须是固定的并且在声明数组时就指定(编译器需要知道数组的长度以便分配内存),数组长度最大为 2G。

访问数组元素对于数组 arr 来说,第一个元素就是 arr[0],第二个元素是 arr[1],最后一个元素则是 arr[len(arr)-1]。下面的代码定义一个整型数组,然后通过 for 循环打印数组中的每个元素:

arr1 := [5]int{10, 20, 30, 40, 50}for i := 0; i < len(arr1); i++ {fmt.Printf("At index %d is %d\n", i, arr1[i])}

输出结果如下

At index 0 is 10
At index 1 is 20
At index 2 is 30
At index 3 is 40
At index 4 is 50

除了使用 len() 函数通过索引遍历数组,还可以使用更方便的 range,结果都是一样的:

for index, value := range arr1 {fmt.Printf("At index %d is %d\n", index, value)}

输出结果同上面完全一致

修改数组元素要修改单个元素的值,直接通过下标访问元素并赋值就可以了:

arr1[0] = 1

指针数组

数组的元素除了是某个类型外,还可以是某个类型的指针,下面声明一个所有元素都是指针的数组,然后使用 * 运算符就可以访问元素指针所指向的值:

arr := [5]*int{0: new(int), 1: new(int)}

new(TYPE) 函数会为一个 TYPE 类型的数据结构划分内存并执行默认的初始化操作,然后返回这个数据对象的指针,所以 new(int) 表示创建一个 int 类型的数据对象,同时返回指向这个对象的指针。

arrPointer := [5]*int{new(int)}
*arrPointer[0] = 2
fmt.Println(*arrPointer[0]) // 输出2
fmt.Println(arrPointer[0]) // 输出 0xc000014118 这是一个内存地址

数组是值类型

在 Golang 中,数组是值类型,这意味着数组也可以用在赋值操作中。变量名代表整个数组,同类型的数组可以赋值给另一个数组:

  var arr2 [5]intarr2 = arr1arr1[3] = 5         // 修改arr1fmt.Println(arr2)  // 这里仍然输出 [10 20 30 40 50] 因为是值类型所以不受影响

把数组赋值给其它数组时,实际上是完整地复制一个数组。

数据是指针类型

如果数组是一个指针型的数组,那么复制的将是指针,而不会复制指针所指向的对象。看下面的代码

  arrPointer := [5]*int{new(int)}*arrPointer[0] = 2fmt.Println(*arrPointer[0])fmt.Println(arrPointer[0])var arr3 [5]*intarr3 = arrPointerfmt.Println(len(arr3))for index, value := range arr3 {fmt.Printf("== At index %d address is %h\n", index, value)}for i := 0; i < len(arr3); i++ {if arr3[i] != nil { // 是空指针会发生panic需要提前判断fmt.Println("at address", arr3[i], " value = ", *arr3[i])}}

结果如下

== At index 0 address is %!h(*int=0xc0000aa0c8)
== At index 1 address is %!h(*int=<nil>)
== At index 2 address is %!h(*int=<nil>)
== At index 3 address is %!h(*int=<nil>)
== At index 4 address is %!h(*int=<nil>)
at address 0xc0000aa0c8  value =  2

Go教程(五) 数组相关推荐

  1. MongoDB 教程五: MongoDB固定集合和性能优化 (索引Indexes, 优化器, 慢查询profile)

    mongodb索引详解(Indexes) 索引介绍 索引在mongodb中被支持,如果没有索引,mongodb必须扫描每一个文档集合选择匹配的查询记录.这样扫描集合效率并不高,因为它需要mongod进 ...

  2. MongoDB 教程五: MongoDB固定集合和性能优化

    MongoDB 固定集合(Capped Collections) MongoDB 固定集合(Capped Collections)是性能出色且有着固定大小的集合,对于大小固定,我们可以想象其就像一个环 ...

  3. 区块链教程(五):合约编写实战实例

    注:本教程为技术教程,不谈论且不涉及炒作任何数字货币 区块连教程(一):前置知识-linux补充 区块链教程(二):基础概念介绍 区块链教程(三):Solidity编程基础 区块链教程(四):搭建私链 ...

  4. c语言程序设计 实验五数组6,实验五 数组——一维数组.doc

    实验五 数组--一维数组 淮海工学院计算机科学系实验报告书 课程名:< C语言程序设计教程> 题 目: 实验五 数组--一维数组 班 级: 学 号: 姓 名: 评语: 成绩: 指导教师: ...

  5. 周游C语言教程9 - 数组

    周游C语言教程9 - 数组 这是周游C语言的第九篇教程,你将在这篇文章里认识数组. 数组 数组就是一组相同的数的集合,数组的声明并不是声明一个个单独的变量,比如a0.a1.-.a99,而是声明一个数组 ...

  6. Swift中文教程(五)--对象和类

    原文:Swift中文教程(五)--对象和类 Class 类 在Swift中可以用class关键字后跟类名创建一个类.在类里,一个属性的声明写法同一个常量或变量的声明写法一样,除非这个属性是在类的上下文 ...

  7. Java-Runoob-高级教程-实例-数组:01. Java 实例 – 数组排序及元素查找

    ylbtech-Java-Runoob-高级教程-实例-数组:01. Java 实例 – 数组排序及元素查找 1.返回顶部 1. Java 实例 - 数组排序及元素查找  Java 实例 以下实例演示 ...

  8. C#微信公众号开发系列教程五(接收事件推送与消息排重)

    C#微信公众号开发系列教程五(接收事件推送与消息排重) 原文:C#微信公众号开发系列教程五(接收事件推送与消息排重) 微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教程一(调试环境部署续 ...

  9. Java-Runoob-高级教程-实例-数组:10. Java 实例 – 查找数组中的重复元素-un

    ylbtech-Java-Runoob-高级教程-实例-数组:10. Java 实例 – 查找数组中的重复元素 1.返回顶部 1. Java 实例 - 查找数组中的重复元素  Java 实例 以下实例 ...

最新文章

  1. mysql链事务_MYSQL 之事务篇
  2. SAP QM物料主数据里QM Material Authorization Group字段
  3. 操作系统课程设计 内核模块
  4. 砂.随笔.二十五.如果你是氧气
  5. python 定义变量_第三章(第2节):变量和常量
  6. java的编辑框丢失焦点_java – 捕获EditText丢失焦点
  7. Magento模型集合addFieldToFilter常用过滤条件
  8. 【OpenCV】OpenCV函数精讲之 -- imwrite()函数
  9. 体积的2 3科学计算机怎么算,小学三年级上册科学第2课-测量体积教案-冀人版
  10. win8下IE10停止工作解决办法
  11. jpype测试报错,找不到类raise _RUNTIMEEXCEPTION.PYEXC(Class %s not found % name)
  12. Jackson 格式化日期问题
  13. 蓝桥杯c语言基础试题答案,2014年蓝桥杯c语言试题及答案
  14. 浪潮服务器自带备份软件,备份软件DPS
  15. 服务器bios 虚拟化,hp服务器bios开启虚拟化(hp主板开启虚拟化)
  16. otool 和 install_name_tool
  17. 笔记本电脑上如何创建html,笔记本怎么创建wifi_笔记本电脑怎么创建无线网络-win7之家...
  18. 横版过关游戏开发-游戏流程
  19. 我喜欢你时的内心活动
  20. 运维日常之机房浪潮服务器硬盘红灯亮起,服务器一直响,raid磁盘红色。。。故障解决方法

热门文章

  1. 【油猴脚本】生成纯元素CSS选择器(附开发笔记)
  2. 怎样用计算机合并视频,怎么合并视频-只需1键,将多个腾讯|爱奇艺|优酷视频瞬间转换成mp4(送转换器)...
  3. [TVM PR 开发随笔] quantized::leakyrelu
  4. SIGCOMM 一些有意思的论文
  5. 爱奇艺手机html页面,手机爱奇艺弹幕消失了
  6. 汽车点火钥匙等定义!
  7. 如何生成你的专属推荐文案?智能文案在1688平台的应用...
  8. 五款文件夹同步工具你会选择谁?(GoodSync/FreeFileSync/SyncToy/Allway Sync/Compare Advance)
  9. SAP KANBAN 从入门到放弃系列之调拨模式
  10. 关于字符串转整型、整型转字符串 Java