douye7033 2017-04-21 15:36
浏览 36
已采纳

如何将切片的副本传递给函数?

I am just learning Go and I have a doubt about passing slices to functions.

If I'm not wrong the slices are passed by reference in Go, so if I do something like this:

package main

import "fmt"

func main() {
    slice := []int{1, 2, 3, 4, 5}
    fmt.Println(slice)
    testSlice(slice)
    fmt.Println(slice)
}

func testSlice(slice []int) {
    slice[0] = 5
    slice[4] = 1
}

The testSlice function will actually change the values in the original slice, because it was passed by reference (by default).

There is some easy way that I can directly pass a copy of the slice to the testSlice function?

Sure I can do something like this to create a copy of the slice:

package main

import "fmt"

func main() {
    slice := []int{1, 2, 3, 4, 5}
    fmt.Println(slice)
    testSlice(slice)
    fmt.Println(slice)
}

func testSlice(slice []int) {
    var newSlice []int
    for i := 0; i < len(slice); i++ {
        newSlice = append(newSlice, slice[i])
    }
    newSlice[0] = 5
    newSlice[4] = 1
}

But it needs to go through all values in the original slice to copy each of them, and it doesn't seem to be a great solution.

  • 写回答

1条回答 默认 最新

  • doutao6380 2017-04-21 15:40
    关注

    There is a built in function, copy, func copy(dst, src []T) int which is probably what you're looking for. It copies a slice of any type into another slice.

    From the docs:

    The copy function supports copying between slices of different lengths (it will copy only up to the smaller number of elements). In addition, copy can handle source and destination slices that share the same underlying array, handling overlapping slices correctly.

    So

    list := []string{"hello", "world"}
    newList := make([]string, len(list))
    n := copy(newList, list)
    // n is the number of values copied
    

    Will copy list into a new slice newList, which share values but not the reference in memory. The int copy returns is the number of values copied.


    For an alternative way, from Kostix's comment, you can append the slice to an empty slice. Which is kind of like copying it. It might not be idiomatic, but it allows you to pass the slice into a func as a copy, sort of. If you do this, I recommend copious comments.

    thisFuncTakesSliceCopy( append([]string(nil), list...) )
    

    To append a slice to another slice, remember the ellipses (...).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 在获取boss直聘的聊天的时候只能获取到前40条聊天数据
  • ¥20 关于URL获取的参数,无法执行二选一查询
  • ¥15 液位控制,当液位超过高限时常开触点59闭合,直到液位低于低限时,断开
  • ¥15 marlin编译错误,如何解决?
  • ¥15 有偿四位数,节约算法和扫描算法
  • ¥15 VUE项目怎么运行,系统打不开
  • ¥50 pointpillars等目标检测算法怎么融合注意力机制
  • ¥20 Vs code Mac系统 PHP Debug调试环境配置
  • ¥60 大一项目课,微信小程序
  • ¥15 求视频摘要youtube和ovp数据集