重学Go语言之数组的具体使用详解

目录
  • 什么是数组
  • 数组的创建
  • 访问数组的元素
  • 数组的长度
  • 如何遍历数组
  • 数组的比较
  • 查找数组中的元素
  • 将数组作为函数参数
  • 二维与多维数组
  • 小结

什么是数组

什么是数组?数组是有固定长度的相同数据类型元素的集合, 如下图所示:

从数组的定义以及上面的示例图我们可以得到数组的三个特征:

  • 固定长度,数组的长度在编译时就要确定。
  • 每个元素的数据类型相同。
  • 数组索引从0开始,索引的最大值为数组长度减1。

数组的创建

直接声明数组变量,在声明时必须指定长度:

var iArray [2]int
var sArray [3]string

上面的代码中,我们创建了一个长度为2,元素数据类型为int的数组和一个长度为3,元素数据类型为string的数组。

声明后,就可以通过索引给对应的元素赋值:

iArray[0] = 1
iArray[1] = 2
sArray[0] = "hello"
sArray[1] = "world"
sArray[2] = "!"

fmt.Println(iArray) //输出 [1,2]
fmt.Println(sArray) //输出 ["hello","world","!"]

也可以在声明时通过花括号{}直接初始化数组元素的值:

var iArray [2]int = [2]int{1,2}

//花括号内初始化元素数量可以少于数组的长度,后面没有初始化的元素会被赋予该数据类型的默认值
var sArray [4]string = [4]string{"A","B","C"}

如果在声明时或者之后没有通过索引给数组的元素赋值,那么元素的值为对应数据类型的初始值:

var iArray [3]int
var sArray [4]string
fmt.Println(iArray) //输出:[0,0,0]
fmt.Println(sArray) //输出:[]

通知短变量可以让数组声明的更简洁:

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

也可以在声明数组不指定数组长度,而是通过...和花括号{}内的初始化值让Go语言自动推断数组的长度:

var i = [...]int{1, 2, 3, 4} //数组长度为4

访问数组的元素

通过索引可以访问数组中的某个元素:

fmt.Println(iArray[0])

无论是给数组的元素赋值,还是访问数组的元素都不超过数组的长度,否则会数组越界的错误,数组的索引从0开始,因此数组的索引取值范围是0~len-1(len表示数组的长度)。

iArray := [2]int{1,2}
sArray := [3]string{"A","B","C"}
iArray[2] = 10 //报错,该数组索引的取值范围是0~1
fmt.Println(sArray[10]) // 报错,该数组索引的取值范围是0~2

数组的长度

Go内置的函数len()可以用于获得数组的长度:

iArray := [4]int{1,2,3,4}
fmt.Println(len(iArray)) // 输出结果:4

如何遍历数组

遍历数组使用for语句,有两种方式:

使用for语句遍历数组:

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

使用for-range遍历数组:

for k,v := range iArray {
	fmt.Println(k,v)
}

for-range遍历数组时,可以获取数组的索引和数组的元素,也可以在遍历时选择忽略索引或者元素值:

for _,v := range iArray { //忽略数组的索引
	fmt.Println(v)
}

for k,_ := range iArray{ //忽略元素
	fmt.Println(k)
}

数组的比较

数组只能进行相等(==)或者不相等(!=)的比较,并且两个进行比较的数组要符合以下要求,否则代码无法通过编译:

  • 数组元素的数据类型必须一致
  • 数组的长度必须一致

当数组满足上面的要求后,如果对应索引元素值相同,则数组相等,否则不相等:

iArray1 := [2]int{1, 2}
iArray2 := [2]int{1, 2}
if iArray1 == iArray2 {
    print("相等")
} else {
    print("不相等")
}
//输出:相等

iArray3 := [2]int{2, 1}
iArray4 := [2]int{1, 2}
if iArray1 == iArray2 {
    print("相等")
} else {
    print("不相等")
}

//输出:不相等

查找数组中的元素

对于数组来说,要查找数组中是否存在某个元素,并返回其对应索引,就要遍历一个数组,并对每个元素进行比较:

sArray := [5]string{"Java","PHP","Go","Python","JavaScript"}

for index, element := range sArray {
	if element == needle {
			fmt.Println(index)
		}
}

如果我们要查找的元素在数组的最后一个,那么要遍历整个数组才能查找到,查找元素的时间复杂度为O(n)

将数组作为函数参数

把数组作为参数传递给函数时,有几个注意的地方:

  • 当把数组作为参数传给函数时,Go会把数组复制一份传给函数,所以数组作为函数参数时是值传递而不是引用传递。
  • 数组作为参数,会被复制,因此如果传递的数组很大,复制就会很耗时。
  • 传递给函数的数组,其长度与数据类型必须函数形参一致,因此复用性很差。
func updateArray(haystack [5]int, index int, value int) error {
	if index >= len(haystack) {
		return errors.New("索引不能超过数组长度")
	}

	haystack[index] = value
	fmt.Println(haystack) //[1 100 3 4 5]
	return nil
}

func main() {
	iArray := [5]int{1, 2, 3, 4, 5}
	updateArray(iArray, 1, 100)
	fmt.Println(iArray) // [1 2 3 4 5]
}

上面这个例子中,我们希望updateArray函数可以修改我们指定索引的元素数组,但实际修改的复制后数组,与我们传给函数的数组无关,解决的办法是传递数组的指针:

func updateArray(haystack *[5]int, index int, value int) error {
	if index >= len(haystack) {
		return errors.New("索引不能超过数组长度")
	}

	haystack[index] = value
	fmt.Println(haystack) //[1 100 3 4 5]
	return nil
}

func main() {
	iArray := [5]int{1, 2, 3, 4, 5}
	updateArray(&iArray, 1, 100)
	fmt.Println(iArray) // [1 100 3 4 5]
}

虽然传递数组指针可以避免数组复制导致的性能问题,但是数组的长度和元素数据类型仍然要求一致,这大概就是数组不怎么被使用的原因吧:

func main() {
	iArray := [6]int{1, 2, 3, 4, 5} //把数组长度改为6
	updateArray(&iArray, 1, 100)  //报错
}

同理,当我们把一个数组变量赋值另外一个变量时,Go也是把数组复制一份给新的变量,如果想把新的变量指向原来的数组,同样是用数组的指针:

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

iArray1 := iArray

iArray[0] = 10

fmt.Println(iArray1) //输出:[10,2]
fmt.Println(iArray) //输出:[1,2]

iArray2 := &iArray
iArray2[0] = 20;

fmt.Println(iArray2) //输出:&[20,2]
fmt.Println(iArray) //输出:[20,2]

二维与多维数组

Go也支持二维和多维数组,其创建方式与一维数组类似:

二维数组:

iArrays := [3][2]string{{"A","B"},{"C","D"},{"E","F"}}

上述二维数组的结构如下图所示:

多维数组:

iArrays := [3][4][2]int{
		{
			{1, 2},
			{3, 4},
			{5, 6},
		},
		{
			{7, 8},
			{9, 10},
			{11, 12},
		},
		{
			{13, 14},
			{15, 16},
			{17, 18},
		},
	}

上述三维数组的结构如下图所示:

小结

总结一下,这篇文章主要讲了以下几点:

  • 数组是一种固定长度的相同数据类型元素的集合,在实际开发中并不常用,而是作为slice的底层数据结构。
  • Go支持一维、二维和多维数组
  • 数组可以进行相等或者不相等的比较
  • 使用for或者for-range可以遍历数组
  • 通过数组索引访问元素或者给元素赋值时,都不能超过数组的长度限制。

到此这篇关于重学Go语言之数组的具体使用详解的文章就介绍到这了,更多相关Go语言 数组内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 使用go语言实现查找两个数组的异同操作

    最近项目上碰到个小需求,输入是两个数组,一个旧数组一个新数组,要求获取新数组相对旧数组所有新增和删除的元素,例如: 输入: arr_old: {"1", "2", "4", "5", "7", "9"} arr_new: {"2", "3", "4", "6", "7"} 返回: arr_

  • Go语言基础学习之数组的使用详解

    目录 1. Array(数组) 2. 声明数组 3. 数组初始化 3.1 方式一 3.2 方式二 3.3 方式三 3.4 多维数组 4. 遍历数组&取值 5. 数组拷贝和传参 数组相必大家都很熟悉,各大语言也都有数组的身影.Go 语言也提供了数组类型的数据结构. 1. Array(数组) 数组是同一种数据类型的固定长度的元素集合.在 Go 语言中,数组声明后长度就不能改变了,可以修改数组的元素,用法: // eg: 定义一个长度为 10 的 int 数组 var a [10]int 2. 声明数

  • 详解Go语言中数组,切片和映射的使用

    目录 1.Arrays (数组) 2.切片 2.1 make创建切片 3.映射Map Arrays (数组), Slices (切片) 和 Maps (映射) 是常见的一类数据结构 1.Arrays (数组) 数组是定长的. 长度不可改变. 初始化 package main import ( "fmt" ) func main() { var scores [10]int scores[0] = 99 fmt.Printf("scoers:%d\n", scores

  • Golang二维数组的使用方式

    ★二维数组的使用方式: 先声明或者定义,再赋值 1)语法:var 数组名[大小][大小]类型 2)比如:var arr[2][3]int[][] 两行三列的二维数组 ★二维数组的遍历 1)双层for循环 2)for-range方式完成遍历 package main import ( "fmt" ) func main() { //演示二维数组的遍历 var arr3 = [2][3]int{{1,2,3},{4,5,6}} //for循环来遍历 for i :=0;i < len

  • 浅析Go语言容器之数组和切片的使用

    目录 序列容器 数组 Vector Deque List 单链表 总结 在 Java 的核心库中,集合框架可谓鼎鼎大名:Array .List.Set.Queue.HashMap 等等,随便拎一个出来都值得开发者好好学习如何使用甚至是背后的设计源码(这类文章也挺多,大家上网随便一搜). 虽然 Go 语言没有如此丰富的容器类型,但也有一些基本的容器供开发者使用,接下来让我们一一认识这些容器类型吧. 序列容器 序列容器存储特定类型的数据元素.目前有 5 种序列容器的实现: array vector

  • 重学Go语言之数组的具体使用详解

    目录 什么是数组 数组的创建 访问数组的元素 数组的长度 如何遍历数组 数组的比较 查找数组中的元素 将数组作为函数参数 二维与多维数组 小结 什么是数组 什么是数组?数组是有固定长度的相同数据类型元素的集合, 如下图所示: 从数组的定义以及上面的示例图我们可以得到数组的三个特征: 固定长度,数组的长度在编译时就要确定. 每个元素的数据类型相同. 数组索引从0开始,索引的最大值为数组长度减1. 数组的创建 直接声明数组变量,在声明时必须指定长度: var iArray [2]int var sA

  • Go语言基础数组用法及示例详解

    目录 概述 语法 注意 示例 概述 固定长度,数组声明后长度便不能再修改 只能存储一种特定类型元素的序列 语法 编号 方式 代码示例 1 直接声明 var arr [3]int 2 make arr:=make([]int,3) 3 字面量 arr:=[3]int{1,2,3} 4 自动识别长度 arr:=[-]int{1,2,3} 5 二维数组 arr := [4][4]int{{1}, {1, 2}, {1, 2, 3}} 6 new arrp := new([10]int) 7 下标取值

  • 重学Go语言之运算符与控制结构详解

    目录 运算符 算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 指针运算符 运算符的优先级 控制结构 If For Switch 小结 运算符 运算符的作用是将操作数组合成表达式,比如下面的代码中,我们通过赋值和加号组成了两个表达式: var i,j = 1,2 n := i + j Go的运算符大体分为六种:算术运算符.关系运算符.逻辑运算符.位运算符.赋值运算符和指针运算符. 算术运算符 运算符 含义 + 加号,除了用于整数,浮点数,复数外,还可以用于字符串的拼接 - 减号 * 相乘

  • 重学Go语言之变量与常量的声明与使用详解

    目录 变量 变量名 声明 变量作用域 常量 iota 常量生成器 小结 变量 什么是变量?变量是一块可以随时存放数据的内存区域.在我们申请这块内存区域(声明变量)时,需要指定变量名以及变量的数据类型,数据类型用于说明变量可以存放什么值. Go是强类型语言,因此Go的变量需要先声明再使用,且声明后不可以改变其数据类型. 变量名 变量名必须以字母或下划线开头. 变量名区分大小写,比如Version和version是两个不同的变量. 不能用关键字(25个)和保留字(37个)给变量命名. 声明 Go语言

  • C语言strlen和sizeof在数组中的使用详解

    目录 一.前言 二.sizeof在二维数组的试题 解读: 题解: 答案验证: 64位平台下: 32位平台下: 一.前言 前面我们详细讲了sizeof和strlen中的使用,基本涉及了所有一维数组可以和常见的题目类型 那么现在我们就将一维数组告一段落了,现在我们来开始讲解在二维数组的使用了,本篇是 sizeof和strlen的最后一篇了. 二.sizeof在二维数组的试题 #include<stdio.h> int main() { int a[3][4] = { 0 }; printf(&qu

  • C语言学习进阶篇之万字详解指针与qsort函数

    目录 前言 函数指针 代码一 代码二 函数指针数组 函数指针数组的用途 计算器的基本代码 函数指针实现简单的计算机 函数指针数组实现简单计算机 指向函数指针数组的指针 回调函数 简单的冒泡排序 冒泡排序的优化 qsort函数 qsort函数介绍 qsort实现冒泡排序 qsort排序结构数据 模拟实现qsort函数 写在最后 前言 前面学到了字符指针,指针数组是一个存储指针的数组,数组指针是一个指向函数的指针,数组参数和指针参数.其中不乏有很多需要注意的知识点,例如:&数组名和数组名表示的含义,

  • C语言从编译到运行过程详解

    目录 C语言从编译到运行 一.前言 二.C程序编译过程 三.阶段过程 1.预处理阶段 2.编译阶段 3.汇编阶段 4.链接阶段 C语言从编译到运行 一.前言 最近在看CSAPP(深入理解计算机系统)然后以前也学过C语言,但是从来没有深究写好的C代码是怎么编译再到执行的. 所以现在自己学习,然后记录下来. 以最常用的hello world!程序为例 程序名: main.c #include <stdio.h> int main() { printf("Hello world!\n&qu

  • C语言中联合体union的实例详解

     C语言中联合体union的实例详解 1.定义: union(int i, short s, char c) un; un.i = 3; printf("i=%d",un.i); printf("length = %d\n",sizeof(un);//==4,有最大的变量来决定 2.相当与java里的List T类型 3.数据交换 void swap(int *p , int *q){ int temp = *p; *p = *q; *q = temp; } 4.打

  • C语言实现“幸运数”的实例详解

    C语言实现"幸运数"的实例详解 1.题目: 标题:幸运数 幸运数是波兰数学家乌拉姆命名的.它采用与生成素数类似的"筛法"生成. 首先从1开始写出自然数1,2,3,4,5,6,-. 1 就是第一个幸运数. 我们从2这个数开始.把所有序号能被2整除的项删除,变为: 1 _ 3 _ 5 _ 7 _ 9 -. 把它们缩紧,重新记序,为: 1 3 5 7 9 -. .这时,3为第2个幸运数,然后把所有能被3整除的序号位置的数删去.注意,是序号位置,不是那个数本身能否被3整除!

  • C语言数据输入与输出实例详解

    C语言数据输入与输出实例详解 1 概论 C语言提供了跨平台的数据输入输出函数scanf()和printf()函数,它们可以按照指定的格式来解析常见的数据类型,例如整数,浮点数,字符和字符串等等.数据输入的来源可以是文件,控制台以及网络,而输出的终端可以是控制台,文件甚至是网页. 2 数据输出 从第一个c语言程序中,就使用了跨平台的库函数printf实现将一段文字输出到控制台,而实际上,printf()不仅可以将数据按照指定的格式输出到控制台,还可以是网页或者是指定的文件中,printf()函数执

随机推荐