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'

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

报告相同问题?

悬赏问题

  • ¥20 测距传感器数据手册i2c
  • ¥15 RPA正常跑,cmd输入cookies跑不出来
  • ¥15 求帮我调试一下freefem代码
  • ¥15 matlab代码解决,怎么运行
  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法