明确理解函数中参数的处理

问题描述 投票:-1回答:2

为了简单的示例,假设我们使用下面的代码读取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变量本身(不是指针)呢?

go
2个回答
0
投票

reflect.SliceHeader的切片类型定义

bs

尽管切片是一个值,但是该值的地址指向指针,因此在扩展之前可以将切片视为ptr属性。

Reader接口修改[] byte对象,就像修改指针一样。最后,Read方法返回修改后数据的长度,即type SliceHeader struct { Data uintptr Len int Cap int } 的长度。]

在触发切片以通过附加进行扩展之后,将创建一个新的切片。新切片的数据地址与扩展地址不同。

在Go中,通道,地图和切片会保存数据地址,因此它们都可以显示指针引用的性质;但是,切片追加方法将在扩展后返回新的数据指针,并显示类似的值传递属性。


0
投票

在此排队:

© www.soinside.com 2019 - 2024. All rights reserved.