登录
首页 >  Golang >  Go问答

阐明函数参数处理的概念

来源:stackoverflow

时间:2024-03-01 08:33:26 280浏览 收藏

在Golang实战开发的过程中,我们经常会遇到一些这样那样的问题,然后要卡好半天,等问题解决了才发现原来一些细节知识点还是没有掌握好。今天golang学习网就整理分享《阐明函数参数处理的概念》,聊聊,希望可以帮助到正在努力赚钱的你。

问题内容

举个简单的例子,假设我们使用下面的代码来读取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 中,变量是按值传递给函数的(因此函数使用传递值的副本而不是原始值本身); go 的 read 方法的文档是:

type Reader interface {
    Read(p []byte) (n int, err error)
}

根据文档,p []byte[]byte 类型,而不是它的指针([]*byte);那么resp.body.read方法是如何直接访问和编辑bs变量本身(不是指针)的呢?


解决方案


reflect.sliceheader 的切片类型定义

type sliceheader struct {
    data uintptr
    len  int
    cap  int
}

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

reader接口修改[]byte对象就像修改指针一样。最后read方法返回修改数据的长度,即n <= len(p)的长度。

切片触发append扩展后,会创建一个新的切片。新切片的数据地址与扩展后的地址不同。

在go中,通道、映射和切片保存了一个数据地址,因此它们都可以表现出指针引用的性质;但是,切片追加方法在扩展后将返回一个新的数据指针,并且将显示类似的值传递属性。

这里的行:

bs := make([]byte, 99999)

当您创建切片时,您实际上创建了一个数组并接收一个指向该数组的指针,名为 bs(slice)。现在,go 隐式地为您执行此操作,并且它是一个抽象层。

现在,排队

resp.Body.Read(bs)

您实际上正在传递一个用于修改的指针。 resp.body.read(bs) 不会对你大喊大叫,因为你通过说“嘿 read(),bs 不是指针,我保证。;)”来欺骗 read()。

以上就是《阐明函数参数处理的概念》的详细内容,更多关于的资料请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>