【Go语言】数组类型

232 阅读18分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第12天,点击查看活动详情

一般初始化数组分析

1. 结构:

var 变量名 [数组⻓度] 数据类型 = [数组⻓度] 数据类型{元素值1,元素值2,元素值3..}

结构分解:img

解析:在Go语言中,数组被称为Array,就是一个由若干相同类型的元素组成的序列。当一个数组被声明时,它里面包含的每个元素都会被初始化为该元素类型的默认值。一旦数组被声明了,那么它的数据类型跟长度都不能再被改变。因此,在初始化元素赋值的过程中所赋值的元素个数最大值和赋值类型都是不能改变的。

2. 举例:声明一个元素值递增的整型数组,且它的数组长度仅为3。

 var arr2 [3]int = [3]int{1, 2, 3}                                       //标准数组初始化
 fmt.Println(arr2) // [1 2 3]                                        //语句&表达式输出

终端输出:img

结构分解:

 var arr2 [3]int = [3]int{1, 2, 3}                                       //标准数组初始化

标准数组初始化* :数组的初始化分为两部分,一部分是数组的内存空间的声明,一部分是内存空间上元素数据的存储,在内存空间声明时,数组被指定数据类型和元素个数(就是数组长度),且一旦被指定声明的数据类型和长度以后,数组就不能再次改动大小(数据长度)了。声明结束以后进入了第二步,数组元素数据的存储,在数组长度不变的基础上,赋给数组与数组同等个数的同类型元素数据,即完成了标准数组的初始化。*

 fmt.Println(arr2) // [1 2 3]                                        //语句&表达式输出

语句&表达式输出:前期我们学习到fmt.Println(...) 可以将变量字符串输出到控制台,并在最后自动增加换行字符 \n。而当将变量换做数组时这样的输出形式依然成立。函数内语句依照main函数内依次执行。

3. 思考: 那我们思考这样一个问题,在go语言中既然变量都存在“:=”短类型声明,那标准化的数组声明结构如此厚重,我们是否可以将之简化:

将上述举例进行实验:将初始化语句替换

 var arr2 = [3]int{1, 2, 3}                                       //简化初始化

终端输出:img

由此可见:go语言中对数组初始化中存在的部分重合声明可以省略,当我们细致观察也会发现,当在标准初始化过程中,如果该处语句可省略,语句就会被指定置灰。如:

img

4. 提升思考:数组声明时有一个巨大特点,那就是声明完成后其数据类型和数据长度都不会被改变。

那么是否可以这样说,我们数组元素的赋值在数据长度固定的情况下可以只赋值部分元素。

将上例进行探究:

 var arr2 = [3]int{1, 2}                                       //部分元素赋值

终端输出: img

我们发现程序没有报错,正常输出,最后一位元素也以整型0输出并没有消失。

原来当元素没有被数据赋值时,它会以数组类型初始化的该数据类型的默认值出现。

5. 那要是我们一不小心赋值过多呢?* 则:*

 var arr2 = [3]int{1, 2, 3, 4}                                 //元素赋值过多

终端输出: img

终端出现报错,显示数组元素赋值超过最大元素赋值个数(数组长度)。

总结:数组元素的初始化赋值个数不能超过即定的数组长度,当元素赋值个数不够时,会由数组的数据类型的默认值来填充。

数组字面值初始化数组分析

数组字面值初始化数组分析

1. 结构:

数组名 := [数组⻓度] 数据类型{value1,value2,value3}

结构分解:img

解析: 在go语言中使用 := (推导声明写法或短类型声明法:编译器会自动根据右值类型推断出左值的对应类型。),可以声明一个数组,并对其进行(显式)初始化

2. 举例:声明一个长度为5的字符串数组并初始化每个元素。

 arr3 := [5]string{"知链", "区块链", "人才", "培养", "摇篮"}        //数组字面值初始化
 fmt.Println(arr3) // [知链 区块链 人才 培养 摇篮]              //语句&表达式输出

终端输出img

结构分解:

 arr3 := [5]string{"知链", "区块链", "人才", "培养", "摇篮"}        //数组字面值初始化

数组字面值初始化: Go语言是静态类型语言,因此数组(variable)也是有明确类型的。编译器会检查函数调用中数组的数据类型类型的正确性。在此语句中通过短类型声明将数组声明并指定出数组类型和数组长度(即数组元素的数据存储的内存空间),然后通过=(赋值运算符)将数据赋值给数组元素的数据存储空间。

fmt.Println(arr3) // [知链 区块链 人才 培养 摇篮]              //语句&表达式输出

语句&表达式输出:前期我们学习到fmt.Println(...) 可以将变量字符串输出到控制台,并在最后自动增加换行字符 \n。而当将变量换做数组时这样的输出形式依然成立。函数内语句依照main函数内依次执行。

不定长度数组初始化分析

不定长度数组初始化分析

1. 结构:

数组名 := [* …] 数据类型{value1,value2,value3}*

结构分解:img

释义:语法糖指的是计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。语法糖让程序更加简洁,有更高的可读性。

解析:在不定长度数组初始化过程中,我们使用‘…’来声明数组长度,其实是‘…’go的一种语法糖,它的主要用法之一就是用于数组或函数有多个不定参数的情况,可以接受多个不确定数量的参数。需要注意的是使用它依然需要符合数组数据类型要相同的基本要求。

2. 举例:初始化一个不确定长度的数组。

arr4 := [...]string{"知链", "-", "区块链", "人才", "培养", "摇篮"}       //不定长度数组初始化
fmt.Println(arr4) // [知链 - 区块链 人才 培养 摇篮]               //语句&表达式输出

终端输出: img

结构分解:

arr4 := [...]string{"知链", "-", "区块链", "人才", "培养", "摇篮"}       //不定长度数组初始化

不定长度数组初始化:在不定长度数组初始化过程中,我们使用‘…’来声明数组长度,通过使用它我们能获取初始化一个不定长度的数组,这也是它作为语法糖的用法之一。可以使数组接受多个不确定数量的元素数据。

fmt.Println(arr4) // [知链 - 区块链 人才 培养 摇篮]               //语句&表达式输出

语句&表达式输出:前期我们学习到fmt.Println(...) 可以将变量字符串输出到控制台,并在最后自动增加换行字符 \n。而当将变量换做数组时这样的输出形式依然成立。函数内语句依照main函数内依次执行。

索引值初始化数组分析

索引值初始化数组分析

1. 结构:

数组名 := [数组⻓度] 数据类型{索引值:value1, 索引值:value2 }

结构分解:img

解析:通过索引值来初始化特定的数组元素,需要注意的是索引下标是从0值开始的。当声明好一个数组以后,依据数组长度依次确定好对应数据元素的内部存储位置,再通过索引找到对应的元素内存空间进行数据赋值。

2. 举例:试写出一个指定元素赋值的字符串类型数组,且数组定长为5。

arr5 := [5]string{0: "知链", 4: "摇篮"}                            //指定元素数组初始化
fmt.Println(arr5) // [知链    摇篮]                              //语句&表达式输出

终端输出:img

结构分解:

arr5 := [5]string{0: "知链", 4: "摇篮"}                            //指定元素数组初始化

指定元素数组初始化:在通过索引下标来指定元素赋值前,必须要求数组要有明确的数据类型,但对数组长度没有具体要求,只需要索引元素在数组长度范围内,换句话说可以使用语法糖来决定长度,要注意的是索引是从0位开始找寻元素的。

fmt.Println(arr5) // [知链    摇篮]                              //语句&表达式输出

语句&表达式输出:前期我们学习到fmt.Println(...) 可以将变量字符串输出到控制台,并在最后自动增加换行字符 \n。而当将变量换做数组时这样的输出形式依然成立。函数内语句依照main函数内依次执行。此处要注意的是,输出中的空格是未被指定赋值的其他数组元素,他们所拥有的值即是数组的数据类型声明所给的默认值,该示例中数组的数据类型是string类型,因此其默认值是空格输出。

获取数组长度分析

1. 结构:

var 变量名 = len(数组)

释义:var为声明变量关键字,len()为go语言内置函数,用来获取长度。

结构解析:img

解析:len函数是Go语言中的内置函数,它可以在go程序中直接被调用,它的作用用于计算数组(包括数组指针),切片(slice)、map、channel、字符串等数据类型的长度。

有趣的是,go语言中的结构体,整型,布尔等类型不能作为参数传给len函数。在获取数组长度的过程中,通过使用内置的len函数能返回数组元素的具体个数,也就是数组的长度。

2. 举例: 获取一个拥有5个元素的字符串类型数组的数组长度。

// TODO: 获取数组的长度
arr1 := [5]string{"知链", "区块链", "人才", "培养", "摇篮"}         //数组字面值初始化
var length = len(arr1)                                        //变量的初始化
fmt.Println(length)                                           //语句&表达式输出

终端输出:img

结构分解:

// TODO: 获取数组的长度
arr1 := [5]string{"知链", "区块链", "人才", "培养", "摇篮"}         //数组字面值初始化

数组字面值初始化: Go语言是静态类型语言,因此数组(variable)也是有明确类型的。编译器会检查函数调用中数组的数据类型类型的正确性。在此语句中通过短类型声明将数组声明并指定出数组类型和数组长度(即数组元素的数据存储的内存空间),然后通过=(赋值运算符)将数据赋值给数组元素的数据存储空间。

var length = len(arr1)                                        //变量的初始化

变量的初始化: 因为Go语言是静态类型语言,因此变量(variable)是有明确类型的。变量的声明,赋值过程都可叫做变量的初始化过程,在Go语言中给变量的初始化分为三个阶段,先创建变量,在内存中开辟空间后再初始化变量,将变量初始化为underfined,最后再进行真正赋值从而完成对变量的完整赋值操作。且变量的赋值通过go语言的内置函数len(),获取到数组arr1的数组长度去赋值给变量。

fmt.Println(length)                                           //语句&表达式输出

语句&表达式输出:前期我们学习到fmt.Println(...) 可以将变量字符串输出到控制台,并在最后自动增加换行字符 \n。函数内语句依照main函数内依次执行。

访问数组元素分析

访问数组元素分析

1. 结构:

var 变量名 数据类型 = 数组名[索引值]

结构分解:img

解析:数组元素通过索引(位置)来读取访问。格式为数组名后加中括号,中括号中为索引的值。需要注意的是数组元素的下标是从0开始的。且数组元素的访问是通过操作符[]来访问数组元素。

2. 举例:访问数组输出下标为1的元素值。

arr2 := [5]string{"知链", "区块链", "人才", "培养", "摇篮"}           //数组字面值初始化
// 获取下标为1的元素值
s2 := arr2[1]                                                   //变量的初始化
fmt.Println(s2)                                                 //语句&表达式输出

终端输出: img

结构解析:

arr2 := [5]string{"知链", "区块链", "人才", "培养", "摇篮"}           //数组字面值初始化

数组字面值初始化:在此语句中通过短类型声明将数组声明并指定出数组类型和数组长度(即数组元素的数据存储的内存空间),然后通过=(赋值运算符)将数据赋值给数组元素的数据存储空间。

// 获取下标为1的元素值
s2 := arr2[1]                                                   //元素的获取

元素的获取:通过短类型声明:=来声明一个新变量s2,再将操作符[]获取指定数组元素的内存数据进行真正赋值给变量s2,从而完成对变量的完整赋值操作。

fmt.Println(s2)                                                 //语句&表达式输出

语句&表达式输出:前期我们学习到fmt.Println(...) 可以将变量字符串输出到控制台,并在最后自动增加换行字符 \n。函数内语句依照main函数内依次执行。

数组元素的修改分析

数组元素的修改分析

1. 结构:

数组名[索引值] = 元素赋值

结构分解:img

解析:数组元素的修改,通过操作符[]来获取索引值,从而指定想要修改的数组元素位置,然后再赋值想要修改的数据元素,完成该位置元素的数据修改。但需要注意的是如果只指定特定元素进行修改却没有进行整个数组的全局打印,该数组被使用时则仍然是原始数组。因此当数组元素被指定修改后,必须对全局打印该数组才会对数组元素的修改有效。

2. 举例:完成一个数组元素的修改,并使它的修改有效。

arr3 := [5]string{"知链", "区块链", "人才", "培养", "摇篮"}             //数组字面值初始化
arr3[0] = "知链科技"                                              //元素赋值
fmt.Println(arr3)                                                 //语句&表达式输出

终端输出:img

结构解析:

arr3 := [5]string{"知链", "区块链", "人才", "培养", "摇篮"}             //数组字面值初始化 

数组字面值初始化:在此语句中通过短类型声明将数组声明并指定出数组类型和数组长度(即数组元素的数据存储的内存空间),然后通过=(赋值运算符)将数据赋值给数组元素的数据存储空间。

arr3[0] = "知链科技"                                              //元素赋值

元素赋值:依旧通过操作符[]来获取指定元素位置,再将新的元素数据赋值到数组元素的指定位置,形成新的数组,但需要注意的是这只修改了指定元素数据的过程量数据,底层的原始数组还是没有变化的。

fmt.Println(arr3)                                                 //语句&表达式输出

语句&表达式输出:前期我们学习到fmt.Println(...) 可以将变量字符串输出到控制台,并在最后自动增加换行字符 \n。函数内语句依照main函数内依次执行。需要注意的是,如果只单纯的对指定数组元素进行重新赋值,并没有全局打印整个数组的情况下, 再次使用时则仍然是原始数组。当数组arr3的数据被重新打印后,就完成了原始数组的数据元素的最终修改。

常规遍历数组分析

1. 结构:

for init; condition; post {

循环体语句

}

释义:init: 一般为赋值表达式,给控制变量赋初值;condition: 关系表达式或逻辑表达式,循环控制条件;post: 一般为赋值表达式,给控制变量增量或减量。

结构分解:img

解析:数组的常规遍历,通过for循环来实现遍历过程,先对表达式 init 赋初值;再判别赋值表达式 init 是否满足给定 condition 条件,若其值为真,满足循环条件,则执行循环体内语句,然后执行 post,进入第二次循环,再判别 condition;否则判断 condition 的值为假,不满足条件,就终止for循环,执行循环体外语句。

2. 举例:通过for循环打印输出一个数组。

arr1 := [5]string{"知链", "区块链", "人才", "培养", "摇篮"}           //数组字面值初始化
// TODO: 标准for循环语句
for i := 0; i < len(arr1); i++ {                                    //for循环打印
   fmt.Println(i, arr1[i])
}

终端输出 :img

结构解析:

arr1 := [5]string{"知链", "区块链", "人才", "培养", "摇篮"}           //数组字面值初始化

数组字面值初始化:在此语句中通过短类型声明将数组声明并指定出数组类型和数组长度(即数组元素的数据存储的内存空间),然后通过=(赋值运算符)将数据赋值给数组元素的数据存储空间。

 // TODO: 标准for循环语句
 for i := 0; i < len(arr1); i++ {                                    //for循环语句
    fmt.Println(i, arr1[i])
 }

for循环语句:在Go中, for循环根据循环计数器或循环变量实现代码的重复执行。函数编译进入for循环语句中时,先执行初始化语句以后开始执行条件判断语句(判断数组的长度与初始化赋值大小比较) 进行判断说明,确定其结果为true还是false,且如果为false时,则循环会结束,如果是true则继续向下执行从而执行循环体语句(循环体打印输出数组对应的索引值和相应的元素数据),循环体语句结束以后执行条件控制语句再重复判断条件的执行,从而实现条件的循环判断输出。

for range结构遍历分析

for range结构遍历分析

1. 结构:

for index,value := range array{

循环体语句

}

释义:第一个返回值 index 是数值的下标。第二个value是在该下标位置的值。他们都是仅在 for 循环内部可见的局部变量。array为循环输出的元素数组。

结构分解: img

解析: for range 结构是Go语言特有的一种的迭代结构,在许多情况下都非常有用,for range 可以遍历数组、切片、字符串、map 及通道(channel)。每个 rune 字符和索引在 for range 循环中是一一对应的,它能够自动根据 UTF-8 规则识别 Unicode 编码的字符。Go语言和其他语言类似,可以通过 for range 的组合,对数组元素进行遍历,遍历时,index 和 value分别代表字符串的索引和字符串中的每一个字符。

2. 举例: 通过go语言特有的for range 循环打印结构打印一个数组。

 // TODO: range循环标准格式
 arr1 := [5]string{"知链", "区块链", "人才", "培养", "摇篮"}           //数组字面值初始化
 for index, value := range arr1 {                                  //for range循环
    fmt.Println(index, value)
 }

终端输出:img

结构解析:

 // TODO: range循环标准格式
 arr1 := [5]string{"知链", "区块链", "人才", "培养", "摇篮"}           //数组字面值初始化

数组字面值初始化:在此语句中通过短类型声明将数组声明并指定出数组类型和数组长度(即数组元素的数据存储的内存空间),然后通过=(赋值运算符)将数据赋值给数组元素的数据存储空间。

for index, value := range arr1 {                                  //for range循环
   fmt.Println(index, value)
}

for range* 循环:for range 结构是Go语言特有的一种的迭代结构,在许多情况下都非常有用,for range 可以遍历数组、切片、字符串、map 及通道(channel)。 在for range 循环打印的过程中依次将数组arr1中的元素依据下标索引依次打印输出元素内存所储存的数据。*

3. 思考:元素打印时依据索引去打印相应的储存数据,那我们能否只获得我们想要的元素值,而省略索引值?

依据上例试运行:

 for _, value := range arr1 {                                   //for range省略循环
    fmt.Println(value)
 }

终端输出:img

以此,我们可以得知:* 在go语言中,我们可以通过 “_”空白标识符来代替索引。*