为了账号安全,请及时绑定邮箱和手机立即绑定

阐明对函数中参数处理的理解

阐明对函数中参数处理的理解

Go
潇潇雨雨 2022-06-06 15:00:55
为了一个简单的例子,假设我们使用下面的代码来读取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 方法在展开后会返回一个新的数据指针,并且会显示出类似的值传递属性。


查看完整回答
反对 回复 2022-06-06
?
慕容708150

TA贡献1831条经验 获得超4个赞

在这里排队:

bs := make([]byte, 99999)

当你制作一个切片时,你实际上创建了一个数组并接收到一个名为 bs(Slice) 的指向该数组的指针。现在 Go 隐含地为你做这件事,它是一个抽象层。

现在,排队

resp.Body.Read(bs)

你实际上是在传递一个修改指针。resp.Body.Read(bs) 不会对你大喊大叫,因为你通过说“嘿 Read(),bs 不是指针,我保证。;)”来愚弄 Read()


查看完整回答
反对 回复 2022-06-06
  • 2 回答
  • 0 关注
  • 98 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信