数组是具有相同唯一类型的一组已编号且长度固定的数据项序列(这是一种同构的数据结构);这种类型可以是任意的原始类型例如整形、字符串或者自定义类型(结构体、接口)。数组长度必须是一个常量表达式,并且必须是一个非负整数,数组下标是从0开始的,并且数组的长度是固定不可变的,数组中元素的地址是连续的。数组长度也是数组类型的一部分,所以[5]int和[10]int是属于不同类型的。

在其它编程语言中,数组一般都是引用类型,而在Go语言中,数组属于值类型。

注意:如果我们想让数组元素类型为任意类型的话可以使用空接口作为类型。当使用值时我们必须先做一个类型判断。

声明数组

Go语言数组声明需要指定元素类型及元素个数,语法格式如下:

//  变量名          [大小]类型
var variable_name [len]variable_type

示例:

定义一个长度为5的数组arr

var arr [5]int

以上我们声明了一个数组arr,但是我们还没有对他进行初始化,但是声明的变量都会有默认值,int类型的变量默认值是0,所以arr数组中的每个元素的值都是0。

Go语言中的数组是一种值类型,所以可以通过 new() 来创建: var arr1 = new([5]int) 。那么这种方式和 var arr2 [5]int 的区别是什么呢?arr1 的类型是 *[5]int ,而 arr2的类型是 [5]int

数组在内存的结构

假如我们声明一个长度为5的数组var arr [5]int,我们来看看这个数组在内存中的结构是怎么样的。

上图就是一个Go语言数组在内存的结构,在这个arr数组中,由于我们声明的是int32类型,所以数组中的每个元素在内存中占用的字节数是32/8=4字节,通过arr数组每个元素16进制地址我们可以发现,数组中后一个元素的地址比前一个元素的地址大4个字节,这个4字节正好是int32类型元素占用的内存大小,由此我们也能得出结论:数组中元素的内存地址是连续的;当声明数组时所有的元素都会被自动初始化为数组类型的默认值(int类型的默认值是0,所以arr中每个元素的默认值都是0);数组的下标识从0开始的。数组arr的地址就是数组第一个元素(下标为0的元素)的地址,通过下图打印arr的地址和arr[0]的地址就可以证明

初始化数组

刚刚声明的数组已经被默认的元素类型零值初始化了,如果我们再次进行初始化怎么做呢,可以采用如下办法:

var arr [5]int
arr = [5]int{1, 2, 3, 4, 5}

Go语言提供了声明加初始化的:=操作符,以让我们在创建数组的时候直接初始化。

arr := [5]int{1, 2, 3, 4, 5}

这种简短变量声明的方式不仅适用于数组,还适用于任何数据类型,这也是Go语言中常用的方式。

我们也可以在定义数组是不明确指定长度,让编译器自动推导出长度,可以使用...来替代具体的长度

arr := [...]int{1, 2, 3, 4, 5}

如果我们只想给数组的部分元素指定值,其他元素采用默认值我们可以采用下面的办法

arr := [5]int{0:3, 4:6}

这种方式表示我们只给数组下标为0的元素赋值为3,下标为4的元素赋值为6,其它元素的值依然是该类型的默认值(int的默认值是0)。

使用数组

数组元素的访问非常简单,通过索引(下标)即可访问数组的元素。

arr := [5]int{1, 2, 3, 4, 5}
fmt.Println(arr[0], arr[1], arr[2], arr[3], arr[4])

修改数组的某个元素也很简单:

arr := [5]int{1, 2, 3, 4, 5}
fmt.Println(arr[0])
arr[0] = 66
fmt.Println(arr[0])

如果我们要循环打印数组中的所有值,一个传统的就是常用的for循环:

for i := 0; i < len(arr); i++ {
fmt.Println(arr[i])
}

不过大部分时候,我们都是使用for rang循环:

for i, v := range arr {
fmt.Println("索引是:", i, "值是:", v)
}

同样类型的数组是可以相互赋值的,不同类型的不行,会编译错误。那么什么是同样类型的数组呢?Go语言规定,必须是长度一样,并且每个元素的类型也一样的数组,才是同样类型的数组。

arr := [5]int{1, 2, 3, 4, 5}

var arr2 [5]int = arr //可以
var arr3 [3]int = arr //不可以

指针数组和数组本身差不多,只不过元素类型是指针。

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

这样就创建了一个指针数组,并且为索引1和3都创建了内存空间,其他索引是指针的零值nil,这时候我们要修改指针变量的值也很简单,如下即可:

array := [5]*int{1: new(int), 3:new(int)}
*array[1] = 1

以上需要注意的是,只可以给索引1和3赋值,因为只有它们分配了内存,才可以赋值,如果我们给索引0赋值,运行的时候,会提示无效内存或者是一个nil指针引用。

panic: runtime error: invalid memory address or nil pointer dereference

要解决这个问题,我们要先给索引0分配内存,然后再进行赋值修改。

arr := [5]*int{1: new(int), 3:new(int)}
arr[0] =new(int)
*arr[0] = 2
fmt.Println(*arr[0])

函数间传递数组

在Go中,数组也是值类型,所以在函数间传递变量时,么就会整个复制,并传递给函数,如果数组非常大,比如长度100多万,那么这对内存是一个很大的开销。

func main() {
array := [5]int{1: 2, 3:4} //[0 2 0 4 0]
modify(array)
fmt.Println(array) //[0 2 0 4 0]
} func modify(a [5]int){
a[1] = 3
}

通过上面的例子,可以看到,数组是复制的,原来的数组没有修改。我们这里是5个长度的数组还好,如果有几百万怎么办,有一种办法是传递数组的指针,这样,复制的大小只是一个数组类型的指针大小。

func main() {
array := [5]int{1: 2, 3:4} //[0 2 0 4 0]
modify(&array)
fmt.Println(array) //[0 333 0 4 0]
} func modify(a *[5]int){
a[1] = 333
}

这里注意,数组的指针和指针数组是两个概念,数组的指针是*[5]int,指针数组是[5]*int,注意*的位置。

数组使用注意事项

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

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

  3. 数组创建后,如果没有赋值,有默认值

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

    字符串类型数组:默认值为""

    bool数组: 默认值为false

    指针数组: 默认值nil

  4. 使用数组的步骤:1.声明数组并开辟空间2.给数组各个元素赋值3.使用数组

  5. 数组的下标从0开始

  6. 数组下标必须在指定范围内使用,否则报panic:数组越界

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

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

  9. 长度是数组类型的一部分,在传递函数参数时,需要考虑数组的长度

Go语言数组的更多相关文章

  1. GO语言数组和切片实例详解

    本文实例讲述了GO语言数组和切片的用法.分享给大家供大家参考.具体分析如下: 一.数组 与其他大多数语言类似,Go语言的数组也是一个元素类型相同的定长的序列. (1)数组的创建. 数组有3种创建方式: ...

  2. C语言 数组 列优先 实现

    C语言数组结构列优先顺序存储的实现 (GCC编译). 从行优先转换为列优先存储方式, 与行优先相比, 不同之处在于改变了数组维界基址的先后顺序, 从而改变了映像函数常量基址. /** * @brief ...

  3. C语言 数组 行优先 实现

    C语言数组结构行优先顺序存储的实现 (GCC编译). /** * @brief C语言 数组 行优先 实现 * @author wid * @date 2013-11-02 * * @note 若代码 ...

  4. 不可或缺 Windows Native (5) - C 语言: 数组

    [源码下载] 不可或缺 Windows Native (5) - C 语言: 数组 作者:webabcd 介绍不可或缺 Windows Native 之 C 语言 数组 示例cArray.h #ifn ...

  5. C语言数组

    在C语言中,对于三维或三维以上数组的使用并没有很好的支持,而且使用率也非常的低,后面会对三维数组做一些简单的分析,这篇文章主要以二维数组来探讨一些C语言中数组使用的相关概念和技巧. 1 一个var[i ...

  6. C语言数组:C语言数组定义、二维数组、动态数组、字符串数组

    1.C语言数组的概念 在<更加优美的C语言输出>一节中我们举了一个例子,是输出一个 4×4 的整数矩阵,代码如下: #include <stdio.h> #include &l ...

  7. Go语言数组的使用

    Go 语言数组 Go 语言提供了数组类型的数据结构. 数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可以是任意的原始类型例如整形.字符串或者自定义类型. 相对于去声明number0 ...

  8. Go 语言数组

    Go 语言提供了数组类型的数据结构. 数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可以是任意的原始类型例如整形.字符串或者自定义类型. 相对于去声明number0, number ...

  9. C语言 > 数组和指针

    C语言 数组和指针 const: 关于指针和const需要注意一些规则.首先,把const数据或非const数据的地址初始化为指向const的指针或为其赋值是合法的. 然而,只能把非const数据的地 ...

  10. Go语言数组和切片的原理

    目录 数组 创建 访问和赋值 切片 结构 初始化 访问 追加 拷贝 总结 数组和切片是 Go 语言中常见的数据结构,很多刚刚使用 Go 的开发者往往会混淆这两个概念,数组作为最常见的集合在编程语言中是 ...

随机推荐

  1. 部署代码review和CI

    公司原先搭了一个代码Review的服务器,由于历史原因,装的是一个32bit的Ubuntu系统,后来由于需要,需要安装gitlab,由于gitlab需要64位系统,所以临时凑合了个vagrant,本质 ...

  2. python 标准库 glob ,python glob 学习

    glob库是最简单的模块之一,内容非常少.用它可以查找符合特定规则的文件路径名.跟使用 windows 下的文件搜索差不多.查找文件只用到三个匹配符: ”*”, 匹配 个或多个字符: “?”, ”?” ...

  3. windows 下安装redis

    https://github.com/MicrosoftArchive/redis/releases redis 服务安装到系统 redis-server.exe --service-install ...

  4. [转]tomcat启动报错too low setting for -Xss

    tomcat启动报错too low setting for -Xss 网上给的答案都是调整Xss参数,其实不是正确的做法, -Xss:每个线程的Stack大小,“-Xss 15120” 这使得tomc ...

  5. 201771010134杨其菊《面向对象程序设计java》第十二周学习总结

    第十二周学习总结 第一部分:理论知识 内容概要: AWT与Swing简介:框架的创建:图形程序设计: 显示图像: 1.AWT组件: 2.Swing 组件层次关系 3 .AWT与Swing的关系:大部分 ...

  6. oracle 关于房贷计算过程

    create or replace procedure fd(p_bj in number, --贷款本金 p_nll in number, --年利率 p_ns in number, --贷款年数 ...

  7. HDU6011

    巨香蕉牛奶猪皮怪的坑人,刚开始想错了,我先建了一个结构体储存每个字母的价值和数量,然后全部情况列出来进行计算,就是一次挪动一个字符看总之的变化,但是我原来错在了每次挪动的是全部相同的那一个字符,后来只 ...

  8. dubbo入门学习 二 RPC框架

    rpc框架解释 谁能用通俗的语言解释一下什么是 RPC 框架? - 远程过程调用协议RPC(Remote Procedure Call Protocol) 首先了解什么叫RPC,为什么要RPC,RPC ...

  9. 在Linux下部署mysql时,使用group by碰到的问题

    mysql使用group by 的时候报错,错误信息如下: 1055:ER_WRONG_FIELD_WITH_GROUP: Expression #2 of SELECT list is not in ...

  10. Codeforces Round #548 (Div. 2) E 二分图匹配(新坑) or 网络流 + 反向处理

    https://codeforces.com/contest/1139/problem/E 题意 有n个学生,m个社团,每个学生有一个\(p_i\)值,然后每个学生属于\(c_i\)社团, 有d天,每 ...