go的切片有三种定义和初始化的方法,此外注意,数组的传递是值传递,但切片是引用传递:
slice切片的基本 *** 作程序:
package main import "fmt" func main() { // 数组的问题在于大小确定,不能修改,而切片是一个动态数组 // 切片定义方法1: s1 := [] string {"C", "C++", "GO", "python"} fmt.Printf("%T\n", s1) // []string是切片类型 fmt.Println(len(s1)) // 4 fmt.Println(s1) // [C C++ GO python] //切片的定义方法2:make // make定义切片需要有长度,但长度是可变的 s2 := make([]string, 5) fmt.Printf("%T\n", s2) // []string是切片类型 fmt.Println(len(s2)) // 5 fmt.Println(s2) // [] // 方法3:数组变切片 arr := [5] string {"C", "C++", "GO", "python", "java"} s3 := arr[1:4] //成为了切片 fmt.Printf("%T\n", s3) // []string是切片类型 fmt.Printf("%T\n", arr) // [5]string是数组类型 fmt.Println(len(s3)) // 3 fmt.Println(s3) // [C++ GO python] // 方法4:new s4 := new([] string) fmt.Printf("%T\n", s4) // *[]string //fmt.Println(len(s4)) // 没有长度 fmt.Println(s4) // &[] // 注意,数组的传递是值传递,但切片是引用传递 }
运行结果:
切片的基本 *** 作增删改查、复制等需要掌握
go语言slice的原理程序:
package main import "fmt" func main() { // slice切片的基本 *** 作 s1 := [] string {"C", "C++", "GO", "python"} // 1. 添加方法:append s1 = append(s1, "Ajax", "JQuery") fmt.Println(s1) // 2. 复制方法:copy s2 := [] string{} copy(s2, s1) fmt.Println(s2) //为什么s2为空,因为没有给定义长度 // 拷贝的时候,目标对象长度为多少就只能复制多少 s3 := make([] string, len(s1)) copy(s3, s1) fmt.Println(s3) // 3.两个切片合并 s2 = append(s1, s3...) // 省略号是规定的参数 fmt.Println(s2) // 4.数组中删除元素:把数组变成切片,再将两个切片合并 s4 := s2[:] // 把数组变成切片 s4 = append(s2[0:2], s2[4:]...) // 再将两个切片合并 fmt.Println(s4) //5.如何判断元素在切片中:使用循环查询 }
运行结果:
slice有容量(cap)和长度(len)两个概念。
程序:
package main import "fmt" func main() { // 不设置cap的时候,len和cap大小一致 s1 := [] string {"C", "C++", "GO", "python"} fmt.Println(len(s1)) fmt.Println(cap(s1)) s2 := make([] int, 5) fmt.Println(len(s2)) fmt.Println(cap(s2)) s3 := make([] int, 5, 8) // 设置了容量cap fmt.Println(len(s3)) // 5 fmt.Println(cap(s3)) // 8 // 通过数组取切片:cap为切片起始位置之后的数组长度 s4 := [10] int {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} s5 := s4[2: 5] fmt.Println(len(s5)) // 3 fmt.Println(cap(s5)) // 8 }
运行结果:
slice的底层是使用数组实现的,同一个数组的切片会共享内存,但如果切片扩容超过切片的原有容量cap会触发扩容机制,该切片就会自己独立开辟全新内存空间。
slice的append扩容问题:扩容阶段因为需要整体开辟全新的内存空间,因此扩容阶段会影响速度。python的list中底层实际上也是数组,也会面临扩容影响速度的问题。python的同一list中可以存不同的数据类型。
go的扩容机制:
程序示例:
运行结果:
go的数组和切片的值传递是引用传递。python的list进行切片以后返回的是全新的的list。
当append函数遇到make会产生的坑make创建切片的时候,如果有初始长度,则append函数后,该插入值在初始长度之后。
程序:
import "fmt" func main() { s1 := make([] int, 5) s1 = append(s1, 6) fmt.Println(s1) }
运行结果:
[0 0 0 0 0 6]
在没有初始长度的情况下,执行append函数结果如下:
程序:
package main import "fmt" func main() { s1 := make([] int, 0) s1 = append(s1, 6) fmt.Println(s1) }
运行结果:
[6]
对比python程序
python和go的切片 *** 作对比程序示例:
# python l1 = [] print(l1) l1.append(1) print(l1)
运行结果:
[] [1]
slice的append扩容问题:扩容阶段因为需要整体开辟全新的内存空间,因此扩容阶段会影响速度。python的list中底层实际上也是数组,也会面临扩容影响速度的问题。python的同一list中可以存不同的数据类型。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)