100天精通Golang(基础入门篇)——第10天:Go语言中的数组_go

🌷 博主 libin9iOak带您 Go to Golang Language.✨
🦄 个人主页——libin9iOak的博客🎐
🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺
🌊 《IDEA开发秘籍》学会IDEA常用操作,工作效率翻倍~💐
🪁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬请批评指正!🐥


100天精通Golang(基础入门篇)

  • 摘要
  • 前言
  • Go语言中的数组
  • 一、数组(Array)
  • 1.1 什么是数组
  • 1.2 数组的语法
  • 1.2 代码案例1
  • 1.2 代码案例2 array_for_range
  • 1.3 多维数组
  • 1.3 代码案例1
  • 1.4 数组是值类型
  • 1.4代码案例
  • 今日学习总结
  • 结语


摘要

本篇文章是100天"学习Golang"系列文章的第10篇,主要介绍了Go语言中的数组以及数组的语法、多维数组、数组是值类型等内容。通过阅读本篇文章,读者能够了解到如何在Go语言中定义和使用数组,并掌握一些实用的代码技巧。

前言

Go语言是一种现代的、快速、并发的编程语言,由于其简单的语法和高效的执行效率,越来越受到广大开发者的青睐。本篇文章是100天学习Golang的第一篇,旨在为初学者提供一份关于Go语言数组的基础入门指南。我们将从数组的定义开始,详细介绍各种语法和技巧,帮助读者快速掌握Go语言数组的基础知识。

Go语言中的数组

本篇文章介绍了Go语言中的数组,包括数组的定义、多维数组、数组的访问和值类型等知识点。掌握这些知识对于进一步学习Go语言非常重要。

一、数组(Array)

在Go语言中,数组(Array)是一种基本的数据结构,用于存储一组固定长度的同种数据类型的数据。数组中每个元素在内存中都是连续存储的。

1.1 什么是数组

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

数组元素可以通过索引(位置)来读取(或者修改),索引从0开始,第一个元素索引为 0,第二个索引为 1,以此类推。数组的下标取值范围是从0开始,到长度减1。

数组一旦定义后,大小不能更改。

数组是一组相同类型对象的集合,每个对象的类型和大小都相同。数组是一种顺序存储结构,因此数组中的元素可以随机访问,数组的下标从0开始,逐个增加。

数组具有以下特点:

  • 数组长度是固定的,不能动态变化。
  • 数组中每个元素的类型和大小都相同。
  • 数组中的元素在内存中是连续存储的,可以随机访问。
  • 数组是值类型,传递时复制整个数组。

1.2 数组的语法

定义一个数组需要指定其元素的类型和长度,在Go语言中的数组定义语法如下:

var 数组名 [元素个数]T

其中,T表示元素的类型,数组名表示数组的名称,元素个数表示数组的长度,长度必须是一个常量表达式。

例如:
var arr [5]int //定义一个长度为5,元素类型为int的数组

可以通过下标访问数组中的元素,下标从0开始,例如:

arr[0] = 1
arr[1] = 2
arr[2] = 3
arr[3] = 4
arr[4] = 5

取数组的长度可以使用len()函数,例如:

length := len(arr) // length等于5

声明和初始化数组

需要指明数组的大小和存储的数据类型。

var variable_name [SIZE] variable_type

示例代码:

var balance [10] float32
var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

初始化数组中 {} 中的元素个数不能大于 [] 中的数字。
如果忽略 [] 中的数字不设置数组大小,Go 语言会根据元素的个数来设置数组的大小:

var balance = []float32{1000.0, 2.0, 3.4, 7.0, 50.0}
balance[4] = 50.0

数组的其他创建方式:

var a [4] float32 // 等价于:var arr2 = [4]float32{}
  fmt.Println(a) // [0 0 0 0]
  var b = [5] string{"ruby", "王二", "rose"}
  fmt.Println(b) // [ruby 王二 rose  ]
  var c = [5] int{'A', 'B', 'C', 'D', 'E'} // byte
  fmt.Println(c) // [65 66 67 68 69]
  d := [...] int{1,2,3,4,5}// 根据元素的个数,设置数组的大小
  fmt.Println(d)//[1 2 3 4 5]
  e := [5] int{4: 100} // [0 0 0 0 100]
  fmt.Println(e)
  f := [...] int{0: 1, 4: 1, 9: 1} // [1 0 0 0 1 0 0 0 0 1]
  fmt.Println(f)

访问数组元素

float32 salary = balance[9]

示例代码:

package main

import "fmt"

func main() {
   var n [10]int /* n 是一个长度为 10 的数组 */
   var i,j int

   /* 为数组 n 初始化元素 */         
   for i = 0; i < 10; i++ {
      n[i] = i + 100 /* 设置元素为 i + 100 */
   }

   /* 输出每个数组元素的值 */
   for j = 0; j < 10; j++ {
      fmt.Printf("Element[%d] = %d\n", j, n[j] )
   }
}

运行结果:

Element[0] = 100
Element[1] = 101
Element[2] = 102
Element[3] = 103
Element[4] = 104
Element[5] = 105
Element[6] = 106
Element[7] = 107
Element[8] = 108
Element[9] = 109

数组的长度

通过将数组作为参数传递给len函数,可以获得数组的长度。

示例代码:

package main

import "fmt"

func main() {  
    a := [...]float64{67.7, 89.8, 21, 78}
    fmt.Println("length of a is",len(a))

}

运行结果:

length of a is 4

您甚至可以忽略声明中数组的长度并将其替换为…让编译器为你找到长度。这是在下面的程序中完成的。

示例代码:

package main

import (  
    "fmt"
)

func main() {  
    a := [...]int{12, 78, 50} // ... makes the compiler determine the length
    fmt.Println(a)
}

遍历数组:

package main

import "fmt"

func main() {  
    a := [...]float64{67.7, 89.8, 21, 78}
    for i := 0; i < len(a); i++ { //looping from 0 to the length of the array
        fmt.Printf("%d th element of a is %.2f\n", i, a[i])
    }
}

使用range遍历数组:

package main

import "fmt"

func main() {  
    a := [...]float64{67.7, 89.8, 21, 78}
    sum := float64(0)
    for i, v := range a {//range returns both the index and value
        fmt.Printf("%d the element of a is %.2f\n", i, v)
        sum += v
    }
    fmt.Println("\nsum of all elements of a",sum)
}

如果您只需要值并希望忽略索引,那么可以通过使用_ blank标识符替换索引来实现这一点。

for _, v := range a { //ignores index  
}

1.2 代码案例1

package main

import "fmt"

func main() {
	/*
		数据类型:
			基本类型:整数,浮点,布尔,字符串
			复合类型:array,slice,map,struct,pointer,function,channel。。。

		数组:
			1.概念:存储一组相同数据类型的数据结构
					理解为容器,存储一组数据
			2.语法:
					var 数组名 [长度] 数据类型
					var 数组名 = [长度] 数据类型{元素1,元素2.。。}
					数组名 := [...]数据类型{元素。。。}

			3.通过下标访问
				下标,也叫索引:index,
				默认从0开始的整数,直到长度减1
				数组名[index]
					赋值
					取值

				不能越界:[0,长度-1]

			4.长度和容量:go语言的内置函数
				len(array/map/slice/string),长度
				cap(),容量
	*/

	var num1 int
	num1 = 100

	num1 = 200
	fmt.Println(num1)
	fmt.Printf("%p\n", &num1)

	//step1:创建数组
	var arr1 [4]int
	fmt.Printf("%p\n", &arr1)
	//step2:数组的访问
	arr1[0] = 1
	arr1[1] = 2
	arr1[2] = 3
	arr1[3] = 4
	fmt.Println(arr1[0]) //打印第一个数值
	fmt.Println(arr1[2]) //打印第三个数值
	//fmt.Println(arr1[4]) //invalid array index 4 (out of bounds for 4-element array)

	fmt.Println("数组的长度:", len(arr1)) //容器中实际存储的数据量
	fmt.Println("数组的容量:", cap(arr1)) //容器中能够存储的最大的数量
	//因为数组定长,长度和容量相同
	arr1[0] = 100
	fmt.Println(arr1[0])

	//数组的其他创建方式
	var a [4]int //同 var a= [4] int
	fmt.Println(a)

	var b = [4]int{1, 2, 3, 4}
	fmt.Println(b)

	var c = [5]int{1, 2, 4}
	fmt.Println(c)

	var d = [5]int{1: 1, 3: 2}
	fmt.Println(d)

	var e = [5]string{"rose", "王二", "ruby"}
	fmt.Println(e)

	f := [...]int{1, 2, 3, 4, 5}
	fmt.Println(f)
	fmt.Println(len(f))
	g := [...]int{1: 3, 6: 5}
	fmt.Println(g)
	fmt.Println(len(g))
}

运行结果:

200
0xc0000a6058
0xc0000d0040
1
3
数组的长度: 4
数组的容量: 4
100
[0 0 0 0]
[1 2 3 4]
[1 2 4 0 0]
[0 1 0 2 0]
[rose 王二 ruby  ]
[1 2 3 4 5]
5
[0 3 0 0 0 0 5]
7

进程 已完成,退出代码为 0

截图:

100天精通Golang(基础入门篇)——第10天:Go语言中的数组_golang_02

1.2 代码案例2 array_for_range

代码案例:

package main

import "fmt"

func main() {
	/*
		数组的遍历:
			依次访问数组中的元素
			方法一:arr[0],arr[1],arr[2]....

			方法二:通过循环,配合下标
				for i:=0;i<len(arr);i++{
					arr[i]
				}
			方法三:使用range
				range,词义"范围"
				不需要操作数组的下标,到达数组的末尾,自动结束for range循环。
					每次都数组中获取下标和对应的数值。

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

	fmt.Println("---------------")
	for i := 0; i < len(arr1); i++ {
		arr1[i] = i*2 + 1
		fmt.Println(arr1[i])
	}
	fmt.Println(arr1)

	fmt.Println("----------------")
	for index, value := range arr1 {
		fmt.Printf("下标是:%d,数值是:%d\n", index, value)
	}

	sum := 0
	for _, v := range arr1 {
		sum += v
	}
	fmt.Println(sum)
}

运行结果:

GOROOT=D:\Go #gosetup
GOPATH=C:\Users\DELL\go #gosetup
D:\Go\bin\go.exe build -o C:\Users\DELL\AppData\Local\JetBrains\GoLand2023.1\tmp\GoLand\___go_build_Day10_Array__1_.exe D:\GolandProjects\Day10-Array\array_for_range.go #gosetup
C:\Users\DELL\AppData\Local\JetBrains\GoLand2023.1\tmp\GoLand\___go_build_Day10_Array__1_.exe
1
2
3
4
5
---------------
1
3
5
7
9
[1 3 5 7 9]
----------------
下标是:0,数值是:1
下标是:1,数值是:3
下标是:2,数值是:5
下标是:3,数值是:7
下标是:4,数值是:9
25

进程 已完成,退出代码为 0

运行截图:

100天精通Golang(基础入门篇)——第10天:Go语言中的数组_go_03

1.3 多维数组

在Go语言中,可以定义多维数组,例如定义一个二维数组:

var arr [3][4]int

其中,第一个方括号表示行数,第二个方括号表示列数,也可以使用初始化列表的方式进行初始化,例如:

arr := [3][4]int{{1,2,3,4}, {5,6,7,8}, {9,10,11,12}}

可以通过下标访问多维数组中的元素,例如:

arr[1][2] = 7

Go 语言支持多维数组,以下为常用的多维数组声明语法方式:

var variable_name [SIZE1][SIZE2]...[SIZEN] variable_type
var threedim [5][10][4]int

三维数组

a = [3][4]int{  
 {0, 1, 2, 3} ,   /*  第一行索引为 0 */
 {4, 5, 6, 7} ,   /*  第二行索引为 1 */
 {8, 9, 10, 11}   /*  第三行索引为 2 */
}

1.3 代码案例1

package main

import "fmt"

func main() {
	/*

		一维数组:存储的多个数据是数值本身
			a1 :=[3]int{1,2,3}

		二维数组:存储的是一维的一维
			a2 := [3][4]int{{},{},{}}

			该二维数组的长度,就是3。
			存储的元素是一维数组,一维数组的元素是数值,每个一维数组长度为4。

		多维数组:。。。


	*/
	a2 := [3][4]int{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}
	fmt.Println(a2)
	fmt.Printf("二维数组的地址:%p\n", &a2)
	fmt.Printf("二维数组的长度:%d\n", len(a2))

	fmt.Printf("一维数组的长度:%d\n", len(a2[0]))
	fmt.Println(a2[0][3]) // 4
	fmt.Println(a2[1][2]) //7
	fmt.Println(a2[2][1]) // 10

	//遍历二维数组
	for i := 0; i < len(a2); i++ {
		for j := 0; j < len(a2[i]); j++ {
			fmt.Print(a2[i][j], "\t")
		}
		fmt.Println()
	}
	fmt.Println("---------------------")
	//for range 遍历二维数组
	for _, arr := range a2 {
		for _, val := range arr {
			fmt.Print(val, "\t")
		}
		fmt.Println()
	}
}

运行结果:

C:\Users\DELL\AppData\Local\JetBrains\GoLand2023.1\tmp\GoLand\___1go_build_Day10_Array.exe
[[1 2 3 4] [5 6 7 8] [9 10 11 12]]
二维数组的地址:0xc000086120
二维数组的长度:3
一维数组的长度:4
4
7
10
1       2       3       4
5       6       7       8
9       10      11      12
---------------------
1       2       3       4
5       6       7       8
9       10      11      12

进程 已完成,退出代码为 0

运行截图:

100天精通Golang(基础入门篇)——第10天:Go语言中的数组_开发语言_04

1.4 数组是值类型

数组是值类型
Go中的数组是值类型,而不是引用类型。这意味着当它们被分配给一个新变量时,将把原始数组的副本分配给新变量。如果对新变量进行了更改,则不会在原始数组中反映。

在Go语言中,数组是值类型,意味着当数组被传递给函数时,整个数组会被复制,而不是传递数组的指针。因此,如果要修改函数中的数组,必须使用指针。

例如:

func modifyArray(arr [5]int) {
    arr[0] = 10
    fmt.Println("arr inside function:", arr)
}

func main() {
    arr := [5]int{1,2,3,4,5}
    modifyArray(arr)
    fmt.Println("arr outside function:", arr)
}

以上代码中输出如下:

arr inside function: [10 2 3 4 5]
arr outside function: [1 2 3 4 5]

代码案例2:

package main

import "fmt"

func main() {  
    a := [...]string{"USA", "China", "India", "Germany", "France"}
    b := a // a copy of a is assigned to b
    b[0] = "Singapore"
    fmt.Println("a is ", a)
    fmt.Println("b is ", b) 
}

运行结果:

a is [USA China India Germany France]  
b is [Singapore China India Germany France]

数组的大小是类型的一部分。因此[5]int和[25]int是不同的类型。因此,数组不能被调整大小。不要担心这个限制,因为切片的存在是为了解决这个问题。

package main

func main() {  
    a := [3]int{5, 78, 8}
    var b [5]int
    b = a //not possible since [3]int and [5]int are distinct types
}

1.4代码案例

代码案例:

package main

import "fmt"

func main() {
	/*
		数据类型:
			基本类型:int,float,string,bool。。
			复合类型:array,slice,map,function,pointer,channel。。

		数组的数据类型:
			[size]type

		值类型:理解为存储的数值本身
			将数据传递给其他的变量,传递的是数据的副本(备份)
				int,float,string,bool,array
		引用类型:理解为存储的数据的内存地址
				slice,map。。
	*/

	//1.数据类型
	num := 10
	fmt.Printf("%T\n", num)

	arr1 := [4]int{1, 2, 3, 4}
	arr2 := [3]float64{2.15, 3.18, 6.19}
	arr3 := [4]int{5, 6, 7, 8}
	arr4 := [2]string{"hello", "world"}
	fmt.Printf("%T\n", arr1) //[4]int
	fmt.Printf("%T\n", arr2) //[3]float64
	fmt.Printf("%T\n", arr3) //[4]int
	fmt.Printf("%T\n", arr4) //[2]string

	//2.赋值
	num2 := num            //值传递
	fmt.Println(num, num2) //10 10
	num2 = 20
	fmt.Println(num, num2) //10 20

	//数组呢
	arr5 := arr1 //值传递
	fmt.Println(arr1)
	fmt.Println(arr5)

	arr5[0] = 1
	fmt.Println(arr1)
	fmt.Println(arr5)

	a := 3
	b := 4
	fmt.Println(a == b)       //比较a和b的数值是否相等
	fmt.Println(arr5 == arr1) //比较数组的对应下标位置的数值是否相等
	//fmt.Println(arr1 == arr2) //invalid operation: arr1 == arr2 (mismatched types [4]int and [3]float64)

}

运行结果:

GOROOT=D:\Go #gosetup
GOPATH=C:\Users\DELL\go #gosetup
D:\Go\bin\go.exe build -o C:\Users\DELL\AppData\Local\JetBrains\GoLand2023.1\tmp\GoLand\___go_build_array_type_go.exe D:\GolandProjects\Day10-Array\array_type.go #gosetup
C:\Users\DELL\AppData\Local\JetBrains\GoLand2023.1\tmp\GoLand\___go_build_array_type_go.exe
int
[4]int
[3]float64
[4]int
[2]string
10 10
10 20
[1 2 3 4]
[1 2 3 4]
[1 2 3 4]
[1 2 3 4]
false
true

进程 已完成,退出代码为 0

运行截图:

100天精通Golang(基础入门篇)——第10天:Go语言中的数组_go_05

今日学习总结

本篇文章主要介绍了Go语言中的数组,包括数组的定义、语法、多维数组、数组是值类型等方面的内容。通过阅读本篇文章,读者可以深入了解Go语言数组的基础知识,并掌握一些实用技巧。总体而言,本篇文章对于初学者非常友好,详细讲解了数组在Go语言中的应用,帮助读者更好地理解并熟练使用Go语言数组。

100天精通Golang(基础入门篇)——第10天:Go语言中的数组_后端_06

结语

通过今天的学习,您已经踏上了Golang的学习之旅。在未来的日子里,您将探索Golang的各个方面,从基础概念到高级技巧,从实际应用到性能优化。
学习一门编程语言是一个持续的过程,每一天都是您向Golang的精通迈进的重要一步。我鼓励您坚持每天学习,保持热情和好奇心,解决挑战并享受成功的喜悦。

在您的学习旅程中,不要忘记参与社区和与其他Golang开发者交流。分享您的见解和经验,向他人学习,并在开源项目或实际应用中展示您的技能。

如果您在学习过程中遇到困难或有任何问题,不要犹豫向社区和专家寻求帮助。持续学习,勇敢探索,您将在Golang领域取得令人瞩目的成就。

最后,感谢您的阅读和支持!祝愿您在未来的每一天中都能够成为一名精通Golang的开发者!

期待听到您在学习过程中的进展和成就。如果您需要进一步的帮助,请随时告诉我。祝您在学习Golang的旅程中取得巨大成功!