Go语言基础之数组切片

Go语言基础之数组切片

目录:

概述

基于数组,数组切片天界了一系列管理功能,可以随时动态扩充存放空间,并且可以随意传递而不会导致所管理的元素被重复复制。

数组切片的数据结构可以抽象为以下3个变量:

  • 一个指向原生数组的指针
  • 数组切片中的元素个数
  • 数组切片已分配的存储空间

创建数组切片

创建数组切片的方法主要有两种:

基于数组

数组切片可以基于一个已存在的数组创建,数组切片可以只使用数组的一部分元素或者整个数组来创建。

package main
import (
"fmt"
)
func main() {
var array1 = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
var arraySlice = array1[:5]
fmt.Println("elements of array1:")
for _, v := range array1 {
fmt.Print(v, " ")
}
fmt.Println("\nelements of arraySlice:")
for _, v := range arraySlice {
fmt.Print(v, " ")
}
}

通过数组的下标范围,创建切片

直接创建

通过内置函数make()可以灵活的创建数组切片。

mySlice := make([]int, 5) //创建一个初始元素为5的数组切片,元素的初始值为0,
mySlice1 := make([]int, 5, 10) //创建一个初始元素为5的数组切片,元素的初始值为0,并预留10个元素的存储空间
mySlice2 := []int{1, 2, 3, 4, 5} //直接创建并初始化包含5个元素的数组切片。

元素遍历

操作数组元素的所有方法都适用于数组切片,数组切片也可以按下标读写元素,用len()函数操作元素个数,支持使用range关键字快速遍历所有元素。

动态增减元素

可动态增减元素个数是数组切片比数组更为强大的功能。与数组相比,数组切片多了一个存储能力(capacity)的概念,即元素个数和分配空间可以是两个不同的值。合理的设置存储能力的值,可以大幅降低数组切片内部重新分配内存块的频率,从而大大提高程序的性能。

数组切片支持GO语言内置的cap()len()函数,cap()函数返回的是数组切片分配的空间大小,len()函数返回的是数组切片中当前所存储的元素个数。

package main
import "fmt"
func main() {
slice1 := make([]int, 5, 10)
fmt.Println("len(slice1):", len(slice1))
fmt.Println("cap(slice1):", cap(slice1))
}
// len(slice1): 5
// cap(slice1): 10

数组切片通过append()函数添加元素,其中,第二个参数是一个不定参数,可根据需求添加如干个元素。甚至可以直接将一个数组切片追加到一个数组切片的末尾

slice1 = append(slice1, 1, 2, 3, 4)
slice2 := []int{8, 9}
slice1 = append(slice1, slice2...)

需要注意的是slice2...中的...,如果没有这个省略号,则会编译报错,这里的左右就是将slice2包含的所有元素打散后传入slice1

数组切片会自动处理存储空间不足的问题。可以通过查看$GOROOT/src/runtime/slice.go源码,其中扩容相关代码如下:

newcap := old.cap
doublecap := newcap + newcap
if cap > doublecap {
newcap = cap
} else {
if old.len < 1024 {
newcap = doublecap
} else {
// Check 0 < newcap to detect overflow
// and prevent an infinite loop.
for 0 < newcap && newcap < cap {
newcap += newcap / 4
}
// Set newcap to the requested cap when
// the newcap calculation overflowed.
if newcap <= 0 {
newcap = cap
}
}
}

基于数组切片创建数组切片

类似于数组切片可以基于一个数组创建,数组切片也可以基于另一个数组切片创建。

oldSlice := []int{1, 2, 3, 4, 5}
newSlice := oldSlice[:3]

其中,选择oldSlice的元素范围可以超过所以包含的元素个数,但是不能超过oldSlice的存储能力(cap()返回的值),超出oldSlice元素的个数部分会使用0补充。

内容复制

通过内置函数copy(),将内容从一个数组切片复制到另一个数组切片。如果两个数组切片不一样大,则会按照较小的数组切片的元素个数进行复制。

slice1 := []int{1, 2, 3, 4, 5}
slice2 := []int{5, 4, 3}
cpoy(slice2, slice1) //只会将slice1的前三个元素复制到slice2中
cpoy(slice1, slice2) //只会将slice2的三个元素复制到slice1的前三个位置
posted @   咕咚!  阅读(551)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示