美文网首页
slice切片做函数参数

slice切片做函数参数

作者: voidFan | 来源:发表于2020-08-08 21:27 被阅读0次

    首先要明确一点:slice作为函数参数是值传递.

            再来分析一下golang中的切片slice底层的实现细节。

    slice内部结构

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

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

            当需要对slice做插入和删除时(如:append操作),由于需要更改slice结构体中的长度字段,值拷贝就行不通了,需要传slice本身在内存中的地址。

    看一个值传递的例子:

    ```

    package main

    import "fmt"

    func processSlice(x []int) {

        x = append(x, 6)

    }

    func main() {

        var numbers = []int{1, 2, 3, 4, 5}

        processSlice(numbers)

        for _, v := range(numbers) {

            fmt.Println(v)

        }

    }

    ```

    >>> 1 2 3 4 5

    再看一个指针传递的例子:

    ```

    package main

    import "fmt"

    func processSlice(x *[]int) {

        *x = append(*x, 6)

    }

    func main() {

        var numbers = []int{1, 2, 3, 4, 5}

        processSlice(&numbers)

        for _, v := range(numbers) {

            fmt.Println(v)

        }

    }

    ```

    >>> 1 2 3 4 5 6

    slice for 循环中删除元素

    方法1:

    ```

    chars:=[]string{"a","a","b"}

    fori:=0;i<len(chars);i++{

        if chars[i]=="a" {

            chars=append(chars[:i],chars[i+1:]...)

            i--// form the remove item index to start iterate next item

    }

    }

    fmt.Printf("%+v",chars)

    ```

    方式2:

    ```

    p := []int{1, -13, 9, 6, -21, 125}

    j := 0

    for _, n := range p {

        if n > 0 {

            p[j] = n   //删除小于零的元素

            j++

        }

    }

    ```

    不改原slice

    ```

    p := []int{1, -13, 9, 6, -21, 125}

    j := 0

    q := make([]int, len(p))

    for _, n := range p {

        if n > 0 {

            q[j] = n   //删除小于零的元素

            j++

        }

    }

    q = q[:j]

    ```

    相关文章

      网友评论

          本文标题:slice切片做函数参数

          本文链接:https://www.haomeiwen.com/subject/flhkdktx.html