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

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


潇潇雨雨
浏览 99回答 2
2回答

动漫人物

reflect.SliceHeader 的切片类型定义type SliceHeader struct {&nbsp; &nbsp; Data uintptr&nbsp; &nbsp; Len&nbsp; int&nbsp; &nbsp; Cap&nbsp; int}虽然slice是一个值,但是值的地址指向一个指针,所以在展开之前可以把slice当作一个ptr属性。Reader 接口修改 []byte 对象就像修改指针一样。最后,Read 方法返回修改数据的长度,即n <= len(p).切片触发追加扩展后,会创建一个新切片。新切片的数据地址与扩展地址不同。在 Go 中,channels、maps 和 slices 保存了一个数据地址,因此它们都可以显示指针引用的性质;但是, slice append 方法在展开后会返回一个新的数据指针,并且会显示出类似的值传递属性。

慕容708150

在这里排队:bs&nbsp;:=&nbsp;make([]byte,&nbsp;99999)当你制作一个切片时,你实际上创建了一个数组并接收到一个名为 bs(Slice) 的指向该数组的指针。现在 Go 隐含地为你做这件事,它是一个抽象层。现在,排队resp.Body.Read(bs)你实际上是在传递一个修改指针。resp.Body.Read(bs) 不会对你大喊大叫,因为你通过说“嘿 Read(),bs 不是指针,我保证。;)”来愚弄 Read()
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go