【Go语言】【6】GO语言的数组

简介:
原创作品,允许转载,转载时请务必以超链接形式标明文章  原始出处 、作者信息和本声明。否则将追究法律责任。 http://qingkechina.blog.51cto.com/5552198/1616321

    在《【4】GO语言类型和为类型增加方法》里说过GO语言除了基础类型(如int、float64、complex128等)之外,还有复合类型,其中就包含本文的数组。对于数组大家都不陌生,在C语言中可以这样声明一个一维数组:int arr[10],那么GO语言是怎么定义的呢?

一、数组的声明

1、数组的声明格式为var arrName [num]type,比如:

var strArr [10]string     // 声明一个由10个字符串组成的一维字符串数组

var byteArr [32]byte      // 声明一个由32个byte组成的一维byte数组

var pointArr [12]*float64  // 声明一个由12个指向float64类型的指针组成的一维指针数组

var twoArrs [3][5]int     //声明了一个由15个int元素组成的二维int数组

读者可能已经发现,数组在声明时就指定了数组的大小,并且后续数组大小不能修改


2、与GO基础类型类似,数组声明之后也被GO赋予了缺省值

wKioL1TykL2gKYGRAAOM6gTSzns729.jpg其缺省的值是由数组元素类型所决定的,int的缺省值为0、string的缺省值为空串、指针的缺省值为nil,这里的nil与Java的null相似 :)


二、数组的初始化

数组的初始化格式为var arrName [num]type = [num]type{value, value, value,....},比如:

var strArr [6]string = [6]string{"a", "b", "c", "d", "e", "f"}

var byteArr [5]byte = [5]byte{32, 23, 42, 26, 21}

var floatArr [3]float64 = [3]float64{3.1415, 2.6728, 1.4114}

var twoArrs [3][5]int = [3][5]int{{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}, {11, 12, 13, 14, 15}}

初始值时显式指定了数组元素的个数


在初始化时能否把数组元素个数去除呢?答案是肯定的,但必须把元素个数变为...,如下所示:

var strArr [6]string = [...]string{"a", "b", "c", "d", "e", "f"}

var byteArr [5]byte = [...]byte{32, 23, 42, 26, 21}

var floatArr [3]float64 = [...]float64{3.1415, 2.6728, 1.4114}

var twoArrs [3][5]int = [...][5]int{{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}, {11, 12, 13, 14, 15}}

读者估计已发现二维数组中的第二个[]中的数值5并没有省略为...,否则会出现use of [...] array outside of array literal错误提示


能否把[...]type也去除掉呢?答案是不行!但可以把数组定义简写为:

strArr := [...]string{"a", "b", "c", "d", "e", "f"}

byteArr := [...]byte{32, 23, 42, 26, 21}

floatArr := [...]float64{3.1415, 2.6728, 1.4114}

twoArrs := [...][5]int{{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}, {11, 12, 13, 14, 15}}


三、使用new声明数组

除了上面方式声明数组之外,还可以使用new声明数组

strArr := [3]string{"山东", "纠正哥", "搞笑"} // 通常初始化数组形式


newStrArr := new([3]string) // 使用new声明数组

newStrArr[0] = "山东"     // 对new声明的数组进行赋值

newStrArr[1] = "纠正哥"

newStrArr[2] = "搞笑"

wKioL1Ty6sKS4BwiAALqtejnUY0920.jpg读者可能已发现使用new声明的数组,在打印时前面有一个&符号,这说明使用new声明的数组返回的是一个指向数组的指针,通过这个指针可以完成对数组元素的赋值,其示意如下:

wKioL1Ty_v_T-YuJAABGi_wKn_0865.jpg


四、数组的比较

intArr := [2]int{1, 2}

strArr := [2]string{"qing", "ke"}

fmt.Println(intArr == strArr)

很明显整型数组和字符串数组是无法比较,此时会抛出mismatched types [2]int and [2]string异常


那么修改为下面代码呢?

intArr1 := [2]int{1, 2}

intArr2 := [3]int{1, 2, 3}

fmt.Println(intArr1 == intArr2)

尽管都是整型数组,但一个是有3个元素的数组,一个是有2个元素的数组,GO语言会认为这是两个不同的类型,从而抛出mismatched types [2]int and [3]int异常


把数组长度都改为2个元素,但元素值不同呢?

intArr1 := [2]int{1, 2}

intArr2 := [2]int{1, 3}

fmt.Println(intArr1 == intArr2)

此时GO语言认为intArr1和intArr2是同一个类型,但由于其元素值不同,所以打印false


把代码修改如下,才会打印true

intArr1 := [2]int{1, 2}

intArr2 := [2]int{1, 2}

fmt.Println(intArr1 == intArr2)


在其它语言中数组之间并不支持==与!=比较,只有GO这种任性语言才提供 :)


五、再论数组的初始化

【例1】:

intArr := [10]int{1,2}

fmt.Println(intArr)

上面声明数组的长度为10,但初始化时只有2个值,哪么此时会不会报错呢?答案是不会,GO会自动把后面的元素赋予缺省值0

wKiom1TzAVyhG9FvAAJCYlhbMPs759.jpg


【例2】:

intArr := [10]int{1: 10, 2: 20, 3: 30, 4: 40, 9: 90}

fmt.Println(intArr)

这种数组初始化的方式很像JSON,它指定第2个元素值为10、第3个元素值为20、第4个元素值为30、第10个元素值为90,其它元素值由于没有指定值,所以使用缺省值

wKiom1TzAmawx7ngAAIjR7NpjYQ141.jpg


六、数组作为函数入参是值传递

package main


import "fmt"


func test(param [10]int) {

    fmt.Printf("In test function the address is : %p\n", &param) // 打印入参的整型数组的地址

}


func main() {

    intArr := [10]int{5: 10} // 声明并初始化一个整型数组

    fmt.Printf("In main function the address is : %p\n", &intArr) // 打印这个整型数组的地址

    test(intArr) // 调用test函数

}

wKioL1TzBVbCkgPeAAM5dAk7a0k388.jpg从运行结果上看main函数中初始化的数组地址为0xc08200a1e0,而把这个数组传给test()函数,在test()函数里面打印入参的地址发现:入参地址为0xc08200a230与main()中初始化的数组并不是同一个,从而说明数组在GO语言中是值传递,而不是C语言的地址传递;这也意味着在test()方法中对入参数组进行修改不会影响main()中数组的元素值


七、数组长度函数

GO语言内置了len()函数,用于读取数组的长度,其使用示例如下:

intArr := [10]int{5: 10}

fmt.Println(len(intArr))

本文出自 “青客” 博客,请务必保留此出处http://qingkechina.blog.51cto.com/5552198/1616321

目录
相关文章
|
12天前
|
Go 开发者
Go语言包的组织与导入 -《Go语言实战指南》
本章详细介绍了Go语言中的包(Package)概念及其使用方法。包是实现代码模块化、复用性和可维护性的核心单位,内容涵盖包的基本定义、命名规则、组织结构以及导入方式。通过示例说明了如何创建和调用包,并深入讲解了`go.mod`文件对包路径的管理。此外,还提供了多种导入技巧,如别名导入、匿名导入等,帮助开发者优化代码结构与可读性。最后以表格形式总结了关键点,便于快速回顾和应用。
108 61
|
14天前
|
存储 Go
Go语言之接口与多态 -《Go语言实战指南》
Go 语言中的接口是实现多态的核心机制,通过一组方法签名定义行为。任何类型只要实现接口的所有方法即视为实现该接口,无需显式声明。本文从接口定义、使用、底层机制、组合、动态行为到工厂模式全面解析其特性与应用,帮助理解 Go 的面向接口编程思想及注意事项(如 `nil` 陷阱)。
|
7天前
|
测试技术 程序员 Go
Go语言测试简明指南:深度解读go test命令
总的来说,go test是 Go 语言中一个强而有力的工具,每个 Go 程序员都应该掌握并把它融入到日常的开发和调试过程中。就像是一个眼镜过滤出的太阳,让我们在宽阔的代码海洋中游泳,而不是淹没。用好它,让我们的代码更健壮,让我们的生产力更强效。
50 23
|
13天前
|
测试技术 Go 开发者
Go语言常见接口设计技巧-《Go语言实战指南》
本文分享了 Go 语言中接口设计的最佳实践与技巧。首先介绍了接口设计原则,包括面向接口编程和接口隔离原则(定义最小化接口)。接着详细讲解了常用技巧:关注行为而非数据、优先返回接口隐藏实现细节、遵循“-er”命名惯例、使用接口组合提升灵活性、通过 Mock 接口简化单元测试,以及避免导出仅内部使用的接口。最后以表格形式总结了各技巧的核心要点,帮助开发者编写更清晰、可维护的代码。
|
11天前
|
Go
【LeetCode 热题100】DP 实战进阶:最长递增子序列、乘积最大子数组、分割等和子集(力扣300 / 152/ 416 )(Go语言版)
本文深入解析三道经典的动态规划问题:**最长递增子序列(LIS)**、**乘积最大子数组** 和 **分割等和子集**。 - **300. LIS** 通过 `dp[i]` 表示以第 `i` 个元素结尾的最长递增子序列长度,支持 O(n²) 动态规划与 O(n log n) 的二分优化。 - **152. 乘积最大子数组** 利用正负数特性,同时维护最大值与最小值的状态转移方程。 - **416. 分割等和子集** 转化为 0-1 背包问题,通过布尔型 DP 实现子集和判断。 总结对比了三题的状态定义与解法技巧,并延伸至相关变种问题,助你掌握动态规划的核心思想与灵活应用!
29 1
|
8天前
|
缓存 安全 Go
Go语言依赖管理与版本控制-《Go语言实战指南》
本章深入探讨Go语言中的依赖管理与版本控制,重点介绍Go Modules的使用方法。内容涵盖依赖管理的重要性、语义化版本控制(SemVer)、查看和管理依赖版本、主版本路径规则、常见操作场景、国内代理加速、依赖安全(go.sum文件)、版本冲突解决及版本锁定与回退等主题。通过学习,读者将掌握如何实现清晰、稳定且可重复构建的项目依赖管理。
|
存储 JSON API
Go语言:RESTful API 服务,急速入门!
REST即表述性状态传递(英文:Representational State Transfer,简称REST),它是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性
554 0
Go语言:RESTful API 服务,急速入门!
|
安全 编译器 Go
Go语言,Protobuf 入门详解!
Protobuf 是 Protocol Buffers 的简称,是一种与语言、平台无关,可扩展的序列化结构化数据的数据描述语言,Protobuf作为接口规范的描述语言,可以作为设计安全的跨语言PRC接口的基础工具。
409 0
Go语言,Protobuf 入门详解!
|
机器学习/深度学习 前端开发 Java
go语言可以做什么?入门Go语言
go语言可以做什么?入门Go语言
|
存储 IDE Java
go语言简单入门
go语言简单入门
223 0

热门文章

最新文章