Slicing a slice pointer passed as argument
我有以下代码:
1 2 3 4 5 6 | func main() { var buf []byte{1, 2, 3, 4, 5} buf = buf[2:] fmt.Println(buf) panic(1) } |
不过,我想将指向
1 2 3 4 5 6 7 8 9 10 | 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:] } |
号
它给了我一个错误,我不能在
错误
对于另一个错误(
1 | *buf = (*buf)[i:] |
你不小心从变量声明中漏掉了一个
1 2 3 4 5 6 7 8 9 | 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:] } |
号
输出(在游乐场上尝试):
1 | [3 4 5] |
注:
注意,规范规定,如果
这种偏差的原因是指向切片的指针非常罕见,因为切片已经是"just"描述符(到基础数组的连续部分),并且切片大部分时间都是在没有指针的情况下传递的,因此,如果在极少数情况下(如本例),确实需要传递指针,则需要明确处理它。另一方面,数组代表所有元素;分配或传递数组复制所有值,因此使用指向数组的指针(而不是指向切片的指针)更为常见,因此有理由对数组指针提供更多的语言支持。
还要注意,您的任务可以通过只需要一个(非指针)切片作为参数类型并返回新的切片值来完成——当然,必须在调用者处分配新的切片值(一个很好的例子是内置的
注2:
如果参数类型是一个切片(而不是指向切片的指针),并且传递一个切片,则不会复制底层数组,只复制切片头。但在本例中,如果您对参数进行切片(这是切片头的副本),并将新切片(切片头)重新分配给参数,那么您只是更改了参数(局部变量)的值,而不是传递的原始值(变量),这就是它无法工作的原因。
有关切片的详细信息,请阅读以下日志:
去切片:使用和内部
数组、片(和字符串):"append"的机制