我有以下代码:
func main() {
var buf []byte{1, 2, 3, 4, 5}
buf = buf[2:]
fmt.Println(buf)
panic(1)
}然而,我希望将指向buf字节切片的指针传递给另一个函数,并在那里对其进行切片,因此如下所示:
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:]
}它给我一个错误,我不能在sliceArr()函数的参数中使用类型[]byte作为类型*[]byte,并且我不能对类型*[]byte进行切片。怎么了?默认情况下,切片不是通过引用传递的吗?我试着在没有指针的情况下这样做,但它不起作用-数组正在被复制。我该怎么做呢?
发布于 2016-06-24 21:01:39
错误cannot use type []byte as type *[]byte in argument to sliceArr()来自您尚未发布的拼写错误(您试图向sliceArr()传递切片而不是指向切片的指针)。
至于另一个错误(cannot slice type *[]byte),您只需使用括号对指针取消引用进行分组:
*buf = (*buf)[i:]并且您意外地在变量声明中遗漏了一个=符号。除此之外,一切都和你写的一样:
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:]
}输出(在Go Playground上试用):
[3 4 5]备注:
请注意specification states,如果p是指向数组的指针,则p[low:high]是(*p)[low:high]的简写,也就是说,会自动取消对指针的引用。如果p是指向切片的指针,这不会自动发生,p[low:high]是无效的,因为您不能对指针切片。因此,在指针指向切片的情况下,您必须手动取消对指针的引用。
出现这种偏差的原因是,指向切片的指针非常少见,因为切片已经是“仅仅”描述符(指向底层数组的连续部分),并且大部分时间是在没有指针的情况下传递切片的,因此如果在极少数情况下(如本例)确实需要传递指针,则需要明确地处理它。另一方面,数组表示所有元素;赋值或传递数组会复制所有值,因此使用指向数组的指针(而不是指向切片的指针)要常见得多-因此,有理由为数组指针提供更多的语言支持。
还请注意,您的任务可以通过只需要一个(非指针)切片作为参数类型并返回新的切片值来实现-当然,必须在调用方分配新的切片值(内置append()函数就是一个很好的例子)。
注意事项#2:
如果参数类型是切片(而不是指向切片的指针),并且您传递了切片,则不复制基础数组,而只复制切片标头。但是在这种情况下,如果您对参数(这是slice头的副本)进行切片,并将新的切片(slice头)重新分配给参数,那么您只是更改了参数(局部变量)的值,而不是所传递的原始值(变量),这就是它不起作用的原因。
有关切片的更多详细信息,请阅读以下博客文章:
https://stackoverflow.com/questions/38013922
复制相似问题