slice切片做函数参数

2020-08-08  本文已影响0人  voidFan

首先要明确一点: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]

```

上一篇 下一篇

猜你喜欢

热点阅读