• go语言切片作为函数参数的研究


    slice作为函数参数是值传递

    golang中的切片slice底层通过数组实现,slice类似一个结构体,其中一个字段保存的是底层数组的地址,还有长度(len) 和 容量(cap)两个字段。

    结构体作为函数参数时是值拷贝,同理,实际上slice作为函数参数时也是值拷贝,在函数中对slice的修改是通过slice中保存的地址对底层数组进行修改,所以函数外的silce看起来被改变了。

    当需要对slice做插入和删除时,由于需要更改长度字段,值拷贝就不行了,需要传slice本身在内存中的地址。

    以删除为例,说明这种情况。

    不通过函数,直接删除slice中的一个元素

    package main
    
    import "fmt"
    
    func main() {
    	si := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
    
    	fmt.Printf("%v  len %d 
    ", si, len(si))
        
    	si = append(si[:3],si[4:]...)
        
    	fmt.Printf("%v  len %d 
    ", si, len(si))
    }
    // ---------输出结果-------------------
    [1 2 3 4 5 6 7 8 9]  len 9 
    [1 2 3 5 6 7 8 9]  len 8 
    // --------成功删除了4  长度减1---------
    

    通过函数,参数是slice变量

    func main() {
    	si := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
    
    	fmt.Printf("%v  len %d 
    ", si, len(si))
        
    	test1(si)
        
    	fmt.Printf("%v  len %d 
    ", si, len(si))
    }
    
    func test1(si []int) {
    	si = append(si[:3], si[4:]...)
    }
    
    // -------------输出结果-------------------
    [1 2 3 4 5 6 7 8 9]  len 9 
    [1 2 3 5 6 7 8 9 9]  len 9 
    // -----4虽然被删除了,但是长度不变,最后面还多了个9,可见不是想要的结果
    

    通过函数,参数是slice变量的地址

    func main() {
    	si := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
    
    	fmt.Printf("%v  len %d 
    ", si, len(si))
        
    	test(&si)
    
    	fmt.Printf("%v  len %d 
    ", si, len(si))
    }
    
    func test(si *[]int) {
    	(*si) = append((*si)[:3], (*si)[4:]...)
    }
    
    
    // ---------输出结果-------------------
    [1 2 3 4 5 6 7 8 9]  len 9 
    [1 2 3 5 6 7 8 9]  len 8 
    // --------成功删除了4  长度减1---------
    
  • 相关阅读:
    Aspnet_regsql.exe命令行使用小结
    ListView用法学习
    < %=...%>< %#... %>< % %>< %@ %>
    jQuery入门简介
    oracle基础琐碎总结删除数据
    WindowsPhone基础琐碎总结数据绑定(一)
    ADO.NET基础琐碎总结参数化查询
    oracle基础琐碎总结Where和Having的区别与联系
    第一次使用 Windows Live Writer
    WindowsPhone基础琐碎总结数据绑定(二)
  • 原文地址:https://www.cnblogs.com/endurance9/p/10347336.html
Copyright © 2020-2023  润新知