doublel83422 2016-06-24 12:52
浏览 120
已采纳

切片作为参数传递的切片指针

I have the following code:

func main() {
    var buf []byte{1, 2, 3, 4, 5}
    buf = buf[2:]
    fmt.Println(buf)
    panic(1)
}

However I want to pass a pointer to buf byte slice to another function, and slice it there, so something like:

func main() {
    var buf []byte{1, 2, 3, 4, 5}
    sliceArr(&buf, 2)
    fmt.Println(buf)
    panic(1)
}

func sliceArr(buf *[]byte, i int) {
    *buf = *buf[i:]
}

It gives me an error that I cannot use type []byte as type *[]byte in argument to sliceArr() function, and that I cannot slice type *[]byte. What's wrong? Aren't slices passed by reference by default? I tried to do this without a pointer but it doesn't work - the array is being copied. How can I do this?

  • 写回答

1条回答 默认 最新

  • dsf12313 2016-06-24 13:01
    关注

    The error cannot use type []byte as type *[]byte in argument to sliceArr() comes from a typo which you haven't posted (you tried to pass a slice and not a pointer to a slice to sliceArr()).

    As to the other error (cannot slice type *[]byte), you just need to use parenthesis to group the pointer dereferencing:

    *buf = (*buf)[i:]
    

    And you accidentally left out a = sign from the variable declaration. Other than that, everything works as you wrote it:

    func main() {
        var buf = []byte{1, 2, 3, 4, 5}
        sliceArr(&buf, 2)
        fmt.Println(buf)
    }
    
    func sliceArr(buf *[]byte, i int) {
        *buf = (*buf)[i:]
    }
    

    Output (try it on the Go Playground):

    [3 4 5]
    

    Note:

    Note that the specification states that if p is a pointer to an array, p[low:high] is shorthand for (*p)[low:high], that is, the pointer is dereferenced automatically for you. This does not happen automatically if p is a pointer to a slice, p[low:high] is invalid as you cannot slice a pointer. So you have to dereference the pointer manually in case of pointers to slices.

    Reason for this deviation is that a pointer to a slice is very rare as slices are already "just" descriptors (to a contiguous part of an underlying array), and slices are passed without a pointer most of the time, so if in the rare case (like this one) you do need to pass a pointer, you need to be explicit about handling it. Arrays on the other hand represent all the elements; assigning or passing arrays copies all the values, so it is much more common to use pointers to arrays (than pointers to slices) - hence it is justified to have more language support for working with array pointers.

    Also note that your task could be achieved by requiring only a (non pointer) slice as the parameter type and returning the new slice value - which of course must be assigned at the caller (a good example for this is the builtin append() function).

    Note #2:

    If the parameter type is a slice (and not a pointer to a slice), and you pass a slice, the underlying array is not copied, only the slice header. But in this case if you slice the argument (which is a copy of the slice header), and you assign back the new slice (slice header) to the argument, you are just changing the value of the parameter (a local variable) and not the original value (variable) that was passed, this is why it won't work.

    Read the following blog posts for more details on slices:

    Go Slices: usage and internals

    Arrays, slices (and strings): The mechanics of 'append'

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

报告相同问题?

悬赏问题

  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?