栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Go中的“值语义”和“指针语义”是什么意思?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Go中的“值语义”和“指针语义”是什么意思?

当您调用一个函数或方法并将参数传递给它时,将根据值创建一个副本,并且该函数只能访问这些副本。

这意味着,如果函数尝试修改/更改副本,则不会更改原始值。

例如:

func main() {    i := 1    fmt.Println("double:", double(i))    fmt.Println("original i:", i)}func double(i int) int {    i *= 2    return i}

输出(在Go Playground上尝试):

double: 2original i: 1

即使

double()
修改了其
i
参数,调用方的变量(已传递其值)也没有改变。

要更改它,我们需要更改签名以期望有一个指针,传递一个指针并修改指向的值:

func main() {    i := 1    fmt.Println("double:", doublep(&i))    fmt.Println("original i:", i)}func doublep(i *int) int {    *i *= 2    return *i}

输出(在Go Playground上尝试):

double: 2original i: 2

因此,如果我们传递一些东西,我们期望如果传递的值被修改,原始值将不会改变,除非我们传递指向它的指针。

指针语义 意味着,即使我们通过“按值”传递某些内容,被调用方仍然可以修改“原始”值,就像我们已经将指针传递给它一样。

例如:

func main() {    is := []int{1, 2}    fmt.Println("double:", doubles(is))    fmt.Println("original is:", is)}func doubles(is []int) []int {    for i := range is {        is[i] *= 2    }    return is}

输出(在Go Playground上尝试):

double: [2 4]original is: [2 4]

即使我们没有传递指针(

is
不是指针),被调用者仍会修改其元素,并且原始切片的值也会更改。

我们说,即使在Go语言中,所有内容都按值传递,但传递的切片具有指针语义,因为如果被调用者修改了元素,它将反映在原始元素中。

推理

Go中的所有内容都按值传递,也是如此。但是,切片是在幕后,是类似结构的数据结构,该数据结构包含指向保存实际元素的基础数组的指针。并且,当您传递切片时,将进行复制,但是只会复制此切片标头(这是切片值)。副本将包含相同的指针,指向相同的后备数组。没有复制后备阵列。因此,当被调用方修改切片的元素时,支持数组的元素也将被修改,这与原始切片的支持数组相同。

在此处了解更多信息:golang切片是否按值传递?

指针语义传递了许多类型,例如切片,地图,通道。

值得注意的是,与切片不同,数组不在行中,数组值表示其所有值,而传递数组则表示其所有元素的副本。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/514842.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号