为了一个简单的例子,假设我们使用下面的代码来读取body一个 http Get 请求: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 中,变量按值传递给函数(因此函数使用传递值的副本而不是原始值本身);Go forRead方法的文档是:type Reader interface { Read(p []byte) (n int, err error)}根据文档,p []byte是类型[]byte而不是它的指针([]*byte);那么该resp.Body.Read方法如何直接访问和编辑bs变量本身(不是指针)?
2 回答
动漫人物
TA贡献1815条经验 获得超10个赞
reflect.SliceHeader 的切片类型定义
type SliceHeader struct {
Data uintptr
Len int
Cap int
}
虽然slice是一个值,但是值的地址指向一个指针,所以在展开之前可以把slice当作一个ptr属性。
Reader 接口修改 []byte 对象就像修改指针一样。最后,Read 方法返回修改数据的长度,即n <= len(p).
切片触发追加扩展后,会创建一个新切片。新切片的数据地址与扩展地址不同。
在 Go 中,channels、maps 和 slices 保存了一个数据地址,因此它们都可以显示指针引用的性质;但是, slice append 方法在展开后会返回一个新的数据指针,并且会显示出类似的值传递属性。
慕容708150
TA贡献1831条经验 获得超4个赞
在这里排队:
bs := make([]byte, 99999)
当你制作一个切片时,你实际上创建了一个数组并接收到一个名为 bs(Slice) 的指向该数组的指针。现在 Go 隐含地为你做这件事,它是一个抽象层。
现在,排队
resp.Body.Read(bs)
你实际上是在传递一个修改指针。resp.Body.Read(bs) 不会对你大喊大叫,因为你通过说“嘿 Read(),bs 不是指针,我保证。;)”来愚弄 Read()
- 2 回答
- 0 关注
- 98 浏览
添加回答
举报
0/150
提交
取消