【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

目录
相关文章
|
4天前
|
监控 算法 Go
Golang深入浅出之-Go语言中的服务熔断、降级与限流策略
【5月更文挑战第4天】本文探讨了分布式系统中保障稳定性的重要策略:服务熔断、降级和限流。服务熔断通过快速失败和暂停故障服务调用来保护系统;服务降级在压力大时提供有限功能以保持整体可用性;限流控制访问频率,防止过载。文中列举了常见问题、解决方案,并提供了Go语言实现示例。合理应用这些策略能增强系统韧性和可用性。
29 0
|
1天前
|
JavaScript 前端开发 Go
Go语言的入门学习
【4月更文挑战第7天】Go语言,通常称为Golang,是由Google设计并开发的一种编程语言,它于2009年公开发布。Go的设计团队主要包括Robert Griesemer、Rob Pike和Ken Thompson,这三位都是计算机科学和软件工程领域的杰出人物。
8 1
|
1天前
|
Go
|
2天前
|
分布式计算 Java Go
Golang深入浅出之-Go语言中的分布式计算框架Apache Beam
【5月更文挑战第6天】Apache Beam是一个统一的编程模型,适用于批处理和流处理,主要支持Java和Python,但也提供实验性的Go SDK。Go SDK的基本概念包括`PTransform`、`PCollection`和`Pipeline`。在使用中,需注意类型转换、窗口和触发器配置、资源管理和错误处理。尽管Go SDK文档有限,生态系统尚不成熟,且性能可能不高,但它仍为分布式计算提供了可移植的解决方案。通过理解和掌握Beam模型,开发者能编写高效的数据处理程序。
130 1
|
2天前
|
算法 关系型数据库 MySQL
Go语言中的分布式ID生成器设计与实现
【5月更文挑战第6天】本文探讨了Go语言在分布式系统中生成全局唯一ID的策略,包括Twitter的Snowflake算法、UUID和MySQL自增ID。Snowflake算法通过时间戳、节点ID和序列号生成ID,Go实现中需处理时间回拨问题。UUID保证全局唯一,但长度较长。MySQL自增ID依赖数据库,可能造成性能瓶颈。选择策略时需考虑业务需求和并发、时间同步等挑战,以确保系统稳定可靠。
107 0
|
2天前
|
缓存 NoSQL Go
Go语言中的分布式锁实现与选型
【5月更文挑战第6天】本文探讨了Go语言中分布式锁的实现,包括Redis、ZooKeeper和Etcd三种方式,强调了选型时的性能、可靠性和复杂度考量。通过代码示例展示了Redis分布式锁的使用,并提出了避免死锁、公平性等问题的策略。结论指出,开发者应根据业务需求选择合适实现并理解底层原理,以确保系统稳定和高效。
124 0
|
2天前
|
NoSQL 算法 Go
Go语言中的分布式事务处理方案
【5月更文挑战第6天】本文探讨了Go语言在分布式事务处理中的应用,包括2PC、3PC和TCC协议。通过示例展示了如何使用Go的`goroutine`和`channel`实现2PC。同时,文章指出了网络延迟、单点故障、死锁和幂等性等常见问题,并提供了相应的解决策略。此外,还以Redis Redlock为例,展示了如何实现分布式锁。理解并实施这些方案对于构建高可用的分布式系统至关重要。
94 0
|
3天前
|
缓存 测试技术 持续交付
Golang深入浅出之-Go语言中的持续集成与持续部署(CI/CD)
【5月更文挑战第5天】本文介绍了Go语言项目中的CI/CD实践,包括持续集成与持续部署的基础知识,常见问题及解决策略。测试覆盖不足、版本不一致和构建时间过长是主要问题,可通过全面测试、统一依赖管理和利用缓存优化。文中还提供了使用GitHub Actions进行自动化测试和部署的示例,强调了持续优化CI/CD流程以适应项目需求的重要性。
41 1
|
3天前
|
Kubernetes Cloud Native Go
Golang深入浅出之-Go语言中的云原生开发:Kubernetes与Docker
【5月更文挑战第5天】本文探讨了Go语言在云原生开发中的应用,特别是在Kubernetes和Docker中的使用。Docker利用Go语言的性能和跨平台能力编写Dockerfile和构建镜像。Kubernetes,主要由Go语言编写,提供了方便的客户端库与集群交互。文章列举了Dockerfile编写、Kubernetes资源定义和服务发现的常见问题及解决方案,并给出了Go语言构建Docker镜像和与Kubernetes交互的代码示例。通过掌握这些技巧,开发者能更高效地进行云原生应用开发。
40 1
|
3天前
|
负载均衡 监控 Go
Golang深入浅出之-Go语言中的服务网格(Service Mesh)原理与应用
【5月更文挑战第5天】服务网格是处理服务间通信的基础设施层,常由数据平面(代理,如Envoy)和控制平面(管理配置)组成。本文讨论了服务发现、负载均衡和追踪等常见问题及其解决方案,并展示了使用Go语言实现Envoy sidecar配置的例子,强调Go语言在构建服务网格中的优势。服务网格能提升微服务的管理和可观测性,正确应对问题能构建更健壮的分布式系统。
25 1