go语言学习
go语言学习
推荐文章
基础语法
1.声明数组
1.1 一维
声明固定大小的数组
var numbers [5]int // 声明一个长度为5的整型数组初始化数组
var numbers [5]int = [5]int{1, 2, 3, 4, 5} // 声明并初始化一个长度为5的整型数组简化初始化
numbers := [5]int{1, 2, 3, 4, 5} // 使用 := 进行声明并初始化不指定长度的初始化
numbers := [5]int{1, 2, 3} // 自动填充剩余元素为零值使用匿名数组初始化
numbers := [...]int{1, 2, 3, 4, 5} // 声明并初始化一个整型数组,编译器自动确定长度make声明
m := make([] int, 5)
1.2 二维
1.多维数组
var matrix [2][3]int // 声明一个二维数组
matrix = [2][3]int{
{1, 2, 3},
{4, 5, 6},
}2.匿名多维数组
matrix := [...][3]int{
{1, 2, 3},
{4, 5, 6},
}只有行可以匿名,列不可以
3.包含不同类型的数组
var mixed [3]interface{} // 声明一个包含不同类型元素的数组
mixed = [3]interface{}{"hello", 42, true}2.切片
2.1 切片和数组的区别
- 固定大小 vs 动态大小
数组:数组的大小是固定的,一旦定义后就不能改变。
例如:var arr [5]int
切片:切片的大小是动态的,可以在运行时增加或减少元素。
例如:var slice []int - 内存分配
数组:数组在内存中是连续的一块区域,所有元素都存储在一起。
切片:切片实际上是一个指向底层数组的引用,它包含三个字段:
ptr:指向底层数组的指针。
len:当前切片的长度。
cap:底层数组的容量。 - 底层数据结构
数组:数组直接存储元素。
示例:[5]int 存储了5个整数。
切片:切片包含一个指向底层数组的指针、长度和容量。
示例:[]int 包含一个指针、长度和容量。 - 性能
数组:访问数组元素非常快,因为它们是连续存储的。
切片:访问切片元素也很快,但由于切片本身不直接存储元素,而是通过指针访问底层数组,因此性能略低于数组。 - 扩容机制
数组:数组的大小固定,无法扩容。
切片:切片可以通过 append 函数自动扩容。当切片的长度超过底层数组的容量时,Go会自动创建一个新的更大的底层数组,并将旧数组的数据复制过去。 - 语法
数组:声明和初始化数组时需要指定大小。
切片:声明和初始化切片时不需要指定大小。
2.2 切片的声明和使用
切片就是不指定长度的数组,访问元素的方式也和数组一样
2.3 切片的截取
三重索引表达式 sli[start:end:cap] 中的三个元素遵循以下规则:
起始索引(start):表示子切片的起始位置。必须是非负整数。如果省略,默认为0。
结束索引(end):表示子切片的结束位置(不包含该位置的元素)。必须大于或等于起始索引。如果省略,默认为切片的长度。
容量(cap):表示子切片的最大容量。必须大于或等于子切片的长度(end - start)。必须小于或等于原始切片的最大容量。如果省略,默认为原始切片的最大容量。
代码示例:
// 初始化一个整数切片sli,包含六个整数元素
sli := [] int {1, 2, 3, 4, 5, 6}
// 打印切片sli的第二个元素(索引为1),输出结果为2
fmt.Println("sli[1] ==", sli[1])
// 打印切片sli的全部元素,输出结果为[1 2 3 4 5 6]
fmt.Println("sli[:] ==", sli[:])
// 打印切片sli从第二个元素开始到末尾的所有元素,输出结果为[2 3 4 5 6]
fmt.Println("sli[1:] ==", sli[1:])
// 打印切片sli从第一个元素开始到第四个元素之前的所有元素,输出结果为[1 2 3 4]
fmt.Println("sli[:4] ==", sli[:4])
// 打印切片sli从第一个元素开始到第三个元素之前的所有元素,输出结果为[1 2 3]
fmt.Println("sli[0:3] ==", sli[0:3])
// 打印切片sli从第一个元素开始到第三个元素之前的所有元素,并且最大容量为4,输出结果为[1 2 3]
fmt.Println("sli[0:3:4] ==", sli[0:3:4])综上得出:一般切片用不到第三个索引参数,且截取范围是左闭右开
2.4 go和Python在切片截取上的区别
Go语言中的切片截取和Python有一些相似之处,但也存在明显的区别:
索引从0开始:两者都采用从0开始的索引方式。
截取操作:两者都支持类似a[start:end]的截取方式,其中start表示起始索引(包含),end表示结束索引(不包含)。
主要区别在于:
省略规则:在Go中,如果省略start,则默认为0;如果省略end,则默认为切片的长度。而在Python中,省略start默认为0;省略end默认为列表的长度。
越界处理:Go语言的切片截取操作会自动处理越界问题,不会抛出错误,而是返回一个可能为空的切片。Python则会在索引或截取操作越界时抛出IndexError或SliceError。
步长:Python支持三参数的切片语法a[start:end:step],允许指定步长并支持反向截取。而Go语言的切片语法不支持步长,仅支持两参数形式a[start:end]。
内存管理:Go语言的切片与原数组共享底层存储,截取操作不会复制数据,只是创建一个新的切片头结构指向原数组的一部分。而Python的切片操作通常会创建新的列表对象。
实现面向对象的特性
在 Go 语言中,没有传统的面向对象编程(OOP)概念如类(class)、继承(inheritance)、构造函数(constructor)等,但它确实支持面向对象编程的一些核心特性,如封装(encapsulation)、多态(polymorphism)等。Go 语言通过结构体(structs)、接口(interfaces)和方法(methods)来实现这些特性。