golang 切片 slice
一.基本介绍
切片是数组的一个引用,因此切片是引用类型。切片的使用与数组类似,遍历,访问切片元素等都一样。切片是长度是可以变化的,因此切片可以看做是一个动态数组。
slice内存中存放的是:切片的首地址,长度len,还有容量cap。从底层来说其实是一个数据结构(struct结构体),其中cap是容量,可以容纳最多元素的个数,默认为2*len
type slice struct {
tptr *[2]int
len int
cap int
}
var 切片名 []类型 如:var a []int
1.切片的三种使用方式:
1)从数组中切,让切片去引用一个已经创建好的数组
func main() { var n1 []int = []int{1, 2, 3, 4, 5, 6, 7, 8, 9} n2 := []int{4, 5, 6} fmt.Println(n1, n2) slice := n1[1:3] //包前不包后[1:3) fmt.Println(slice) }
2)make创建切片,make([]数据类型, 长度len, 容量cap) 其中容量可以省略
func main() { var sli1 []int = make([]int, 4, 10) sli1[0] = 100 sli1[2] = 200 fmt.Println(sli1) }
3)直接定义 var s1 []int = []int{1,2,3}
func main() { s1 := []int{1, 2, 3, 4, 5} fmt.Println(s1) }
2.追加元素,用append内置函数,可以对切片进行动态追加。因为数组是不可扩容的,所以使用append函数之后是重新生成了一个make([]int, 7,14)的s1新数组,其len和cap都扩大了,然后将原来的s1中的元素拷贝到这个新数组,再添加两个新元素赋值给新数组s1,原来的数组s1就作废了
func main() { s1 := []int{1, 2, 3, 4, 5} s1 = append(s1, 100, 200) fmt.Println(s1) }
3.copy操作,内置函数copy将s2切片中的值拷贝到s3中将s3中的前len(s2)个的元素值覆盖掉。s2和s3的数据空间是相互隔离的,互不影响。若将s2[2]设置为10,则s3[2]仍为3而不随着s2[2]的改变而改变。
若len[s3] 小于len[2] 执行也不会报错,s2只会拷贝len[s3]个元素给s3
func main() { var s2 = []int{1, 2, 3, 4, 5} var s3 = make([]int, 10) copy(s3, s2) fmt.Println(s3) } //[1 2 3 4 5 0 0 0 0 0]
4.string可以用切片的方式来截取
func main() { str := "hello@golang" str = str[6:] fmt.Println(str) }//golang
5.string字符串的元素是不可变的,也不能通过str[0] = 'z'的方式来修改字符串。如果需要修改字符串,可以先将string -> []byte/或者[]rune ->修改 ->再重写成string 如:hello@golang -> zello@golang
如果string有中文,不能使用[]byte来处理,[]byte是按字节进行处理的,可以处理英文和数字,但是一个汉字是3个字节,处理汉字会出现乱码。因此汉字需要使用[]rune来处理,[]rune是按照字符来处理的,兼容汉字
func main() { //hello@golang -> zello@golang str := "hello@golang" arr1 := []byte(str) arr1[0] = 'z' str = string(arr1) fmt.Println(str) }
6.使用切片完成斐波那契数列,在f1函数中需要设置var arr1 []int = make([]int, n1),若只是定义var arr1 []int,默认是len(arr1)为0,只适用于append的情况,而不能之前赋值arr[0] = 1
func f1(n1 int) []int { var arr1 []int = make([]int, n1) arr1[0] = 1 arr1[1] = 1 for i := 2; i < n1; i++ { arr1[i] = arr1[i-1] + arr1[i-2] } return arr1 } func main() { var n1 int //var res []int fmt.Println("请输入一个数字:") fmt.Scanln(&n1) res := f1(n1) fmt.Println(res) }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?