golang入门slice切片的原理以及内置函数cap, len

golang中slice(切片)是常用的类型, slice是对数组进行封装

package main

import (
"fmt"
"strconv"
)

func testLenCap() {
strs := make([]string, 5, 10) //可以只有一个数字参数, 那么cap=len, make([]string, 5, 5) 等价于 make([]string, 5)
fmt.Printf("value=%v, is nil=%v\n", strs, strs == nil)
//strs := []string{"0", "1", "2", "3", "4"} //当然这种方式是直接赋值了, 忽略赋值等价于 make([]string, 5)

for i := 0; i < len(strs); i++ {
strs[i] = strconv.Itoa(i)
}
fmt.Printf("len=%v, cap=%v, strsAddress=%p, valueAddress=%p\n", len(strs), cap(strs), &strs, strs) //%p内存地址

for i := len(strs); i < cap(strs); i++ {
//strs[i] = strconv.Itoa(i) //panic
strs = append(strs, strconv.Itoa(i)) //使用append向数组追加数据
}
fmt.Printf("len=%v, cap=%v, strsAddress=%p, valueAddress=%p\n", len(strs), cap(strs), &strs, strs) //内存地址不变

strs = append(strs, "10")
fmt.Printf("len=%v, cap=%v, strsAddress=%p, valueAddress=%p\n", len(strs), cap(strs), &strs, strs) //内存地址改变

//strs2自身的地址与strs不一样, 但实际数组的内存地址不变, 改变strs, strs2其中任意一个变量, 另一个随之改变
strs2 := strs[:]
fmt.Printf("len=%v, cap=%v, strsAddress=%p, valueAddress=%p\n", len(strs2), cap(strs2), &strs2, strs2)
strs2[5] = "1000"
fmt.Printf("strs[5]=%s\n", strs[5])

//strs3自身的地址与strs不一样, 实际数组的内存地址也不一样, 互不干扰.
startIndex := 5
strs3 := strs[startIndex:7]
fmt.Printf("len=%v, cap=%v, strsAddress=%p, valueAddress=%p\n", len(strs3), cap(strs3), &strs3, strs3)
fmt.Printf("cap(strs3) == cap(strs)-startIndex : %v", cap(strs3) == cap(strs)-startIndex)
}

func main() {
testLenCap()

}

 

控制台打印结果:

value=[ ], is nil=false
len=5, cap=10, strsAddress=0xc0420023e0, valueAddress=0xc04203e0a0
len=10, cap=10, strsAddress=0xc0420023e0, valueAddress=0xc04203e0a0
len=11, cap=20, strsAddress=0xc0420023e0, valueAddress=0xc042040140
len=11, cap=20, strsAddress=0xc0420024a0, valueAddress=0xc042040140
strs[5]=1000
len=2, cap=15, strsAddress=0xc0420024e0, valueAddress=0xc042040190
cap(strs3) == cap(strs)-startIndex : true

 

可以看到:

len函数是实际数据存长度; 

cap是最大容量,可以避免反复分配内存;

使用原切片创建新切片时, 应注意每个切片的值, 避免出现与预想不一样的情况

 



 

posted @ 2019-03-09 23:09  knox大树  阅读(1306)  评论(0编辑  收藏  举报