• 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 ", 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 ", 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 ", len(strs), cap(strs), &strs, strs) //内存地址不变

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

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

    //strs3自身的地址与strs不一样, 实际数组的内存地址也不一样, 互不干扰.
    startIndex := 5
    strs3 := strs[startIndex:7]
    fmt.Printf("len=%v, cap=%v, strsAddress=%p, valueAddress=%p ", 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是最大容量,可以避免反复分配内存;

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



  • 相关阅读:
    解决pandas_datareader的get_data_yahoo不能读取数据的问题
    python 中使用pandas_datareader 报错 ImportError: cannot import name ‘is_list_like’
    loc、iloc、ix 区别
    利用list元素求和组成某一个固定值
    测试id
    Oracle数据库从入门到精通 多表查询知识以及范例
    Oracle数据库从入门到精通 单行函数问题
    Oracle从入门到精通 限定查询和排序查询的问题
    关于Oracle中sys、system和Scott用户下的数据库连接问题
    Java学习笔记——关于位运算符的问题
  • 原文地址:https://www.cnblogs.com/-xuzhankun/p/10503629.html
Copyright © 2020-2023  润新知