为了简单的示例,假设我们使用下面的代码读取http Get请求的body
:
func main() {
resp, err := http.Get("http://google.com")
defer resp.Body.Close()
if err != nil {
log.Fatalln(err)
}
bs := make([]byte, 99999)
resp.Body.Read(bs)
fmt.Println(string(bs))
}
据我所知,在Go中,变量按值传递给函数(因此,函数使用传递的值的副本,而不是原始值本身); documentation of Go for Read
method是:
Read
根据文档,type Reader interface {
Read(p []byte) (n int, err error)
}
的类型为p []byte
,而不是其指针([]byte
);那么[]*byte
方法如何直接访问和编辑resp.Body.Read
变量本身(不是指针)呢?
reflect.SliceHeader的切片类型定义
bs
尽管切片是一个值,但是该值的地址指向指针,因此在扩展之前可以将切片视为ptr属性。
Reader接口修改[] byte对象,就像修改指针一样。最后,Read方法返回修改后数据的长度,即type SliceHeader struct {
Data uintptr
Len int
Cap int
}
的长度。]
在触发切片以通过附加进行扩展之后,将创建一个新的切片。新切片的数据地址与扩展地址不同。
在Go中,通道,地图和切片会保存数据地址,因此它们都可以显示指针引用的性质;但是,切片追加方法将在扩展后返回新的数据指针,并显示类似的值传递属性。
在此排队: