golang 切片

slice#

切片的底层类似一个struct

Copy
struct{ ptr *[]byte//指针 len int//长度 cap int//容量(扩容原理) }

slice知识点#

Copy
package main import ( "fmt" ) func test(slice []int) { slice[0] = 100 //会改变切片的值,因为传进来的切片是指针,属于实参传递了 //这里有可能会造成内存泄露 //重点!!!,这里跟c++的vector区别 } func main() { var intArr [5]int = [...]int{1, 22, 33, 66, 99} slice := intArr[1:3] //等效于 [1.3) fmt.Println(slice) fmt.Println(&intArr[1]) fmt.Println(&slice[0]) //cap类似c++vector扩容原理 //相当于切片和数组共用一个内存,但切片三个部分组成 //指向的引用(数组的地址) 长度(len) 大小(cap) //类似struct的结构 //struct{ // ptr *[2]int // len int // cap int //} //切片的第一种用法 var strslice []string = []string{"tom", "ammy", "bob"} fmt.Println(strslice) fmt.Println(len(strslice)) fmt.Println(cap(strslice)) //切片的第二种用法 类似make 但cap跟len一样 var doubleslice []float64 = make([]float64, 5, 10) doubleslice[1] = 1.0 doubleslice[3] = 12.2 fmt.Println(&doubleslice[0]) fmt.Println(doubleslice) fmt.Println(len(doubleslice)) fmt.Println(cap(doubleslice)) //切片的第三种用法var name []type = make([]type,len,cap) //对于第一种,结构是一样的,但对外是不显示[]float64这个数组,只能靠doubleslice去访问 //类似struct的结构 //struct{ // ptr *[5]float64 // len int // cap int //} //切片循环 var intarry [7]int = [...]int{1, 2, 3, 4, 5, 6, 7} //intslice := intarry[1:4] //[1,4) //intslice := intarry[:4] //[0,4) //intslice := intarry[1:len(intarry)] //[1,7] intslice := intarry[:] //[0,7] //for基本版 for i := 0; i < len(intslice); i++ { fmt.Printf("intslie[%v]:%v\n", i, intslice[i]) } //for-range fmt.Println() for i, v := range intslice { fmt.Printf("intslie[%v]:%v\n", i, v) } strslice = append(strslice, "ammi") fmt.Println(strslice, len(strslice), cap(strslice)) //cap变为6 扩容 slice = append(slice, 1, 2, 3) //切片改变,但不改变原本的intArr数组 fmt.Println(slice) fmt.Println(intArr) slice = append(slice, slice...) //切片double // !后者只能是切片,不能是数组 or else // !后者只能是切片,不能是数组 or else fmt.Println(slice, len(slice), cap(slice)) //copy 深拷贝 //copy 深拷贝 var slice2 []int = make([]int, 12) copy(slice2, slice) fmt.Println(slice2) test(slice2) fmt.Println(slice2) }

string&slice#

Copy
package main import ( "fmt" ) func main() { //string底层是一个byte数组,因此string也可以切片处理 str := "abcdefg@123" //使用切片获取到123 slice := str[8:] fmt.Println(slice) //str[0]='z' //直接报错,原因是string是不可变的,不能按照这样改 //修改的话,过程:string->[]byte/或者[]rune->修改重写转成string arr1 := []byte(str) arr1[0] = 'z' str = string(arr1) fmt.Println(str) //细节 这种只能处理英文和数字,无法处理中文(三个字节) //细节 这种只能处理英文和数字,无法处理中文(三个字节) //要修改中文 使用[]rune arr2 := []rune(str) arr2[0] = '中' str = string(arr2) fmt.Println(str) }

slice内存泄漏与防止#

用新空数组append,用扩容机制防止内存共用问题

(扩容可以让头部指针变化,数据分开,不会导致一个切片被回收导致另外一个(跟前者有同一块底层数组)形成孤儿数据)

posted @   ouluy  阅读(39)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示
CONTENTS