zoukankan      html  css  js  c++  java
  • GO语言复合类型03---切片


    切片相当于长度可以动态扩张的数组

    array[start:end]从数组身上截取下标为[start,end)片段,形成切片
    start代表开始下标,不写默认代表从头开始切
    end代表结束下标(本身不被包含),不写默认截取到末尾

    func main041() {
    	var array = [10]int{0, 11, 22, 33, 44, 55, 66, 77, 88, 99}
    
    	//含头不含尾,从array的第0项截取到第9项
    	slice := array[0:10]
    	fmt.Printf("array的类型是%T,值是%v
    ", array, array) //[10]int
    	fmt.Printf("slice的类型是%T,值是%v
    ", slice, slice) //
    
    	slice = array[0:5]
    	fmt.Printf("slice的类型是%T,值是%v
    ", slice, slice) //[]int
    
    	slice = array[2:5]
    	fmt.Printf("slice的类型是%T,值是%v
    ", slice, slice)//[]int [22 33 44]
    
    	slice = array[:5]
    	fmt.Printf("slice的类型是%T,值是%v
    ", slice, slice)//[]int [0 11 22 33 44]
    
    	slice = array[2:]
    	fmt.Printf("slice的类型是%T,值是%v
    ", slice, slice)//[]int [22 33 44 55 66 77 88 99]
    
    	slice = array[:]
    	fmt.Printf("slice的类型是%T,值是%v
    ", slice, slice)//[]int [0 11 22 33 44 55 66 77 88 99]
    
    	//也可以对切片进行截取,得到切片
    	sonSlice := slice[:]
    	fmt.Printf("sonSlice的类型是%T,值是%v
    ", sonSlice, sonSlice)//[]int [0 11 22 33 44 55 66 77 88 99]
    }
    

    向切片中追加元素&遍历切片

    func main042() {
    
    	//初始化一个没有元素的整型切片
    	var slice []int = []int{}
    	fmt.Printf("类型是%T
    ", slice)                     //[]int
    	fmt.Printf("切片的长度是%d,值是%v
    ", len(slice), slice) //0,[]
    
    	slice = append(slice, 0)
    	fmt.Printf("切片的长度是%d,值是%v
    ", len(slice), slice) //1,[0]
    
    	slice = append(slice, 11, 22, 33)
    	fmt.Printf("切片的长度是%d,值是%v
    ", len(slice), slice) //4,[0 11 22 33]
    
    	//for i := 0; i < len(slice); i++ {
    	//	fmt.Printf("slice的第%d个元素的值是%v
    ", i, slice[i])
    	//}
    
    	for index, value := range slice {
    		fmt.Printf("slice的第%d个元素是%v
    ", index, value)
    	}
    }
    

    cap(slice)获得切片的容量
    创建之初,容量等于长度
    扩张时,一旦容量无法满足需要,就以翻倍的策略扩容

    func main043() {
    	var slice = []int{1, 2, 3} //len=3,cap=3
    	slice = append(slice, 4)
    	fmt.Printf("slice的长度是%d,容量是%d
    ", len(slice), cap(slice))//len=4 cap=6
    
    	slice = append(slice, 1)
    	fmt.Printf("slice的长度是%d,容量是%d
    ", len(slice), cap(slice))//len=5 cap=6
    
    	slice = append(slice, 2)
    	fmt.Printf("slice的长度是%d,容量是%d
    ", len(slice), cap(slice))//len=6 cap=6
    
    	slice = append(slice, 3)
    	fmt.Printf("slice的长度是%d,容量是%d
    ", len(slice), cap(slice))//len=7 cap=12
    
    	slice = append(slice, 4)
    	fmt.Printf("slice的长度是%d,容量是%d
    ", len(slice), cap(slice))//len=8 cap=12
    	slice = append(slice, 5)
    	fmt.Printf("slice的长度是%d,容量是%d
    ", len(slice), cap(slice))//len=9 cap=12
    	slice = append(slice, 6)
    	fmt.Printf("slice的长度是%d,容量是%d
    ", len(slice), cap(slice))//len=10 cap=12
    	slice = append(slice, 7)
    	fmt.Printf("slice的长度是%d,容量是%d
    ", len(slice), cap(slice))//len=11 cap=12
    	slice = append(slice, 8)
    	fmt.Printf("slice的长度是%d,容量是%d
    ", len(slice), cap(slice))//len=12 cap=12
    	slice = append(slice, 9)
    	fmt.Printf("slice的长度是%d,容量是%d
    ", len(slice), cap(slice))//len=13 cap=24
    	slice = append(slice, 10)
    	fmt.Printf("slice的长度是%d,容量是%d
    ", len(slice), cap(slice))//len=14 cap=24
    	slice = append(slice, 11, 12, 13, 14, 15, 16)
    	fmt.Printf("slice的长度是%d,容量是%d
    ", len(slice), cap(slice))//len=20 cap=24
    	slice = append(slice, 17)
    	fmt.Printf("slice的长度是%d,容量是%d
    ", len(slice), cap(slice))//len=21 cap=24
    
    	for i := 18; i < 33; i++ {
    		slice = append(slice, i)
    	}
    
    	fmt.Printf("slice的长度是%d,容量是%d
    ", len(slice), cap(slice))//len=36 cap=48
    }
    

    兼并另一个切片

    func main044() {
    	var slice1 = []int{1, 2, 3} //len=3,cap=3
    	slice2 := []int{5, 6, 7, 8}
    
    	//slice1兼并slice2
    	//for _, value := range slice2 {
    	//	slice1 = append(slice1, value)
    	//}
    	slice1 = append(slice1, slice2...)
    	fmt.Println(slice1)
    }
    

    创建指定长度和容量的切片

    func main045() {
    
    	//var slice []int = []int{3,1,4,1,5}
    
    	//创建长度为3的整型切片
    	//slice := make([]int, 3)
    	//创建长度为3、容量为5的整型切片
    	slice := make([]int, 3, 5)
    	fmt.Println(slice)
    	fmt.Println(len(slice), cap(slice))
    
    	slice = append(slice, 4, 5)
    	fmt.Println(slice,len(slice), cap(slice))//[0 0 0 4 5] 5 5
    
    	slice = append(slice, 4, 5)
    	fmt.Println(slice,len(slice), cap(slice))//[0 0 0 4 5 4 5] 7 10
    }
    

    扩容策略:容量不够时,容量*2(有时+2),找到一片新的连续内存,将原有元素拷贝过去

    func main046() {
    
    	//创建一个0长度(容量默认和长度一样)的整型切片
    	slice := make([]int, 0)
    	fmt.Println(slice, len(slice), cap(slice)) //[],0,0
    
    	slice = append(slice, 1)
    	fmt.Println("len=",len(slice),"cap=",cap(slice),"s=", slice,"首元素地址 =",&slice[0]) //1,1,[1]
    	slice = append(slice, 2)
    	fmt.Println("len=",len(slice),"cap=",cap(slice),"s=",slice,"首元素地址 =",&slice[0],&slice[1])//2,2,[1 2],地址变化
    	slice = append(slice, 3)
    	fmt.Println("len=",len(slice),"cap=",cap(slice),"s=",slice,"首元素地址 =",&slice[0],&slice[1])//3,4,[1 2 3],地址变化
    	slice = append(slice, 4)
    	fmt.Println("len=",len(slice),"cap=",cap(slice),"s=",slice,"首元素地址 =",&slice[0])//4,4,[1 2 3 4]
    	slice = append(slice, 5)
    	fmt.Println("len=",len(slice),"cap=",cap(slice),"s=",slice,"首元素地址 =",&slice[0])//5,8,[1 2 3 4 5],地址变化
    	slice = append(slice, 6,7)
    	fmt.Println("len=",len(slice),"cap=",cap(slice),"s=",slice,"首元素地址 =",&slice[0])//7,8,[1 2 3 4 5 6 7]
    	slice = append(slice, 8,9,10)
    	fmt.Println("len=",len(slice),"cap=",cap(slice),"s=",slice,"首元素地址 =",&slice[0])//10,16,[1 2 3 4 5 6 7 8 9 10],地址变化
    }
    

    切片扩容的一刹那,所有元素的地址都重新拷贝到了一片新的连续内存中

    func main047() {
    	var array = [5]int{0, 1, 2, 3, 4}
    
    	//切片不是拷贝,而是地址引用
    	slice1 := array[:]
    	slice2 := slice1[:]//len=5,cap=5
    
    	//array,slice1,slice2的具有完全相同的元素初始地址
    	//fmt.Printf("%p,%p,%p
    ", &array, &slice1, &slice2)//各不相同(栈内存)
    	fmt.Printf("%p,%p,%p
    ", &array[0], &slice1[0], &slice2[0])//相同
    	fmt.Printf("%p,%p,%p
    ", &array[1], &slice1[1], &slice2[1])//相同
    
    	//牵一发而动全身
    	array[1] = 11
    	slice1[2] = 222
    	slice2[3] = 3333
    	fmt.Println(array)  //[0,11,222,3333,4]
    	fmt.Println(slice1) //[0,11,222,3333,4]
    	fmt.Println(slice2) //[0,11,222,3333,4]
    
    	//slice2扩容之后,所有元素的地址都发生了迁移(拷贝了一份)
    	slice2 = append(slice2, 5,6,7)
    	array[0] = 10
    	slice1[1] = 111
    	slice2[0] = 1000
    	fmt.Println(array)  //[10,111,222,3333,4]
    	fmt.Println(slice1) //[10,111,222,3333,4]
    	fmt.Println(slice2) //[1000,11,222,3333,4]
    
    	fmt.Printf("cap2=%d
    ",cap(slice2))
    	fmt.Printf("%p,%p,%p
    ", &array[0], &slice1[0], &slice2[0])//相同
    }
    

      

  • 相关阅读:
    keepalived排错
    shell脚本记录
    mysql(mariadb)主从配置
    添加硬盘设备
    天数
    centos7网络配置总结
    Keepalibed监控nginx
    zabbix安装
    基于JWT的web api身份验证及跨域调用
    C# webapi 权限验证
  • 原文地址:https://www.cnblogs.com/yunweiqiang/p/11816943.html
Copyright © 2011-2022 走看看