数组,切片
数组
数组的声明
数组是一个由固定长度的特定类型元素组成的序列,一个数组可以由零个或多个元素组成。
var name [size] type
name
: 数组名称
size
: 数组长度
type
: 数组中数据类型
package main
import "fmt"
func main() {
var Arrayllist [5] int //定义长度为 3 ,数据类型为int ,名为 Arrayllist 的数组
for i := 0; i < len(Arrayllist); i++ { //遍历数组
fmt.Println("Arrayllist[", i, "]: ", Arrayllist[i]) //输出
}
}
输出结果:
数组初始化
- 静态初始化:
给出初始化值,由系统决定长度
var Arrayllist = [...]int8{1, 2, 3, 4, 5,6,7,8,9,10}
//或者
Arrayllist := [...]int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
- 动态初始化:
只指定长度,由系统给出初始化值
var Arrayllist = [5] int8 {1,2,3,4,5}
//或者
Arrayllist := [5] int8 {1,2,3,4,5}
遍历数组
可以使用for循环来遍历数组:
package main
import "fmt"
func main() {
var Arrayllist [5] int //定义长度为 3 ,数据类型为int ,名为 Arrayllist 的数组
for i := 0; i < len(Arrayllist); i++ { //遍历数组
fmt.Println("Arrayllist[", i, "]: ", Arrayllist[i]) //输出
}
}
切片
Go 语言切片(Slice)是对数组的抽象。
Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go 中提供了一种灵活,功能强悍的内置类型切片(“动态数组”),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。
可以理解为切片是一个有着自动扩容功能的数组。
切片的声明
切片的声明和数组类似,只不过不需要定义长度。
var name []type //声明切片
name
: 切片名
type
: 切片里的数据类型
因为切片是引用类型,可以使用make
函数来声明一个切片。
var name []int = make([]type, len)
//或者
var name = make([]type, len)
//或者
name := make([]type, len)
len
: 切片初始长度
也可以指定容量,其中 capacity
为可选参数
make([]type, len, capacity)
切片的初始化
直接初始化
var Silce = []int{1, 2, 3, 4, 5}
截取数组进行初始化
var ArrayList = [5]int{1, 2, 3, 4, 5} //声明数组 ArrayList
// ArrayList[startIndex:endIndex]
var Silce []int = ArrayList[0:4] //声明Silce,Silce的值是截取数组,第一个到第四个
startIndex : 开始下标(左包含)
endIndex : 结束下标,但不包含结束下标对应的值(右不包含)
package main
import "fmt"
func main() {
var ArrayList = [5]int{1, 2, 3, 4, 5} //声明数组 ArrayList
var Silce []int = ArrayList[0:4] //声明Silce,Silce的值是截取数组,第一个到第四个
fmt.Println(Silce) //输出切片
}
输出结果:
遍历切片
和数组一样,切片也是可以使用for循环遍历的:
package main
import "fmt"
func main() {
var ArrayList = [5]int{1, 2, 3, 4, 5} //声明数组 ArrayList
var Silce []int = ArrayList[0:4] //声明Silce,Silce的值是截取数组,第一个到第四个
for i := 0; i < len(Silce); i++ { //遍历切片
fmt.Println(Silce[i])
}
}
补充
空切片
如果只是单纯的声明一个切片,会导致声明成了一个空(nil
)切片,空切片的长度为0,
需要使用append()
函数来给空切片添加值。
package main
import "fmt"
func main() {
var Silce_A []int
Silce_A = append(Silce_A, []int{1, 2, 3, 4, 5}...) //使用append为空切片添加元素
if Silce_A == nil { //条件判断
fmt.Println("len(Silce_A) =", len(Silce_A)) //输出切片长度
} else {
fmt.Println("len(Silce_A) =", len(Silce_A))
}
}
输出结果:
append函数 和 copy 函数
copy 来拷贝切片
append 函数用来给切片添加新元素
两数组相互独立,不受影响
package main
import "fmt"
func main() {
var Silce = []int{1, 2, 3}
Silce = append(Silce, 4) //append
fmt.Println("Silce =", Silce)
var SilceCopy = make([]int, len(Silce))
copy(SilceCopy, Silce) //copy
if SilceCopy == nil {
fmt.Println("SilceCopy is nil")
} else {
fmt.Println("SilceCopy = ", SilceCopy)
}
fmt.Println("-------------------------")
Silce = append(Silce, 5) //给切片Silce添加元素
fmt.Println("Silce =", Silce) //输出
fmt.Println("SilceCopy = ", SilceCopy)
}
输出结果:
使用append来实现删除切片元素
Go中没有提供专门删除元素的函数,而是通过切片本身的特点来删除元素。
即以被删除元素为分界点,再利用append将前后两个部分的内存重新连接起来。
name = append(name[:index], name[index+1:]...)
index : 要删除的元素下标
package main
import "fmt"
func main() {
var Silce = []int{1, 2, 3, 4, 5}
//Silce[:3]只能取到下标为0 1 2 的元素,取不到下标为 3 的元素
//而Silce[4:]... 能取到包含下标为 4 的元素,实际效果就是下标前移
//实现删除的效果
Silce = append(Silce[:3], Silce[4:]...) //删除下标为3的元素
fmt.Println(Silce)
}
len函数和cap函数
切片是可索引的,并且可以由 len() 方法获取长度。
切片提供了计算容量的方法 cap() 可以测量切片最长可以达到多少。
package main
import "fmt"
func main() {
var ArrayList = [10]int{1, 2, 3, 4, 5, 6, 7, 8} //声明数组ArrayList长度为10
var Silce []int = ArrayList[0:4] //声明Silce,Silce的值是截取数组,第一个到第四个
fmt.Println("len(Silce) = ", len(Silce)) //获取长度
fmt.Println("cap(Silce) = ", cap(Silce)) //切片最长可以达到多少
}
输出结果:
可见如果是截取数组的切片,长度和截取的原数组长度有关。
如果是声明并且初始化的数组,最大长度是初始长度,而使用append函数添加后,最大长度会自动变化。
package main
import "fmt"
func main() {
var Silce = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
fmt.Println("len(Silce) = ", len(Silce)) //声明并初始化的切片长度
fmt.Println("cap(Silce) = ", cap(Silce)) //声明并初始化的切片最大长度
Silce = append(Silce, []int{11, 12, 13, 14, 15}...)
fmt.Println("len(Silce)Append = ", len(Silce)) //使用Append添加一次后的切片长度
fmt.Println("cap(Silce)Append = ", cap(Silce)) //使用Append添加一次后的切片最大长度
Silce = append(Silce, []int{16, 17, 18, 19, 20, 21}...)
fmt.Println("len(Silce)Append2 = ", len(Silce)) //使用Append添加第二次次后的切片长度
fmt.Println("cap(Silce)Append2 = ", cap(Silce)) //使用Append添加第二次后的切片最大长度
}
输出结果: