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

范围循环中指针和值切片之间的差异

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

范围循环中指针和值切片之间的差异

答:在调用函数之前先评估参数。在对它们进行评估之后,调用的参数将按值传递给函数,并且被调用函数开始执行,因此:

第一

go v.print()
是语法糖
go (*field).print(&v)

所述第二
go v.print()
是语法糖
go (*field).print(v)

如果

for
在goroutines启动之前第一个循环完成,
&v
则调用相同,这三个调用都相同。通过
time.Sleep(100)
gov.print()
第一个循环之后添加,请参见代码2 。或
go func(v field) { v.print() }(v)
在The Go
Playground(带有的代码3
sync.WaitGroup
)上使用

另外,您在这里有 数据竞赛 (请参阅B)。

而对于第二个

go (*field).print(v)
位置
v
是之前调用参数评估真实指针和三个够程
print
,并 有三种不同的地址

1-在The Go Playground上尝试:

package mainimport (    "fmt"    "time")type field struct {    name string}func (p *field) print() {    fmt.Println(p.name)}func main() {    fmt.Println("use values:")    // use values in range loop and go rountines    values := []field{{"one"}, {"two"}, {"three"}}    for _, v := range values {        fmt.Println(&v)        go (*field).print(&v) //go v.print()    }    time.Sleep(time.Second)    fmt.Println()    fmt.Println("use pointers:")    // use pointers in range loop and go rountines    poniters := []*field{{"one"}, {"two"}, {"three"}}    for _, v := range poniters {        fmt.Println(v)        go (*field).print(v) //go v.print()    }    time.Sleep(time.Second)}

输出:

use values:&{one}&{two}&{three}threethreethreeuse pointers:&{one}&{two}&{three}twoonethree

2-在Go Playground上尝试:

package mainimport (    "fmt"    "time")type field struct {    name string}func (p *field) print() {    fmt.Println(p.name)}func main() {    fmt.Println("use values:")    // use values in range loop and go rountines    values := []field{{"one"}, {"two"}, {"three"}}    for _, v := range values {        fmt.Println(&v)        go v.print() //go (*field).print(&v) //        time.Sleep(100)    }    time.Sleep(time.Second)    fmt.Println()    fmt.Println("use pointers:")    // use pointers in range loop and go rountines    poniters := []*field{{"one"}, {"two"}, {"three"}}    for _, v := range poniters {        fmt.Println(v)        go v.print() //go (*field).print(v) //    }    time.Sleep(time.Second)}

输出:

use values:&{one}one&{two}two&{three}threeuse pointers:&{one}&{two}&{three}onetwothree

B:您之间存在数据争夺,请尝试

go build -race

您的代码,然后运行生成的文件
WARNING: DATA RACE

输出:

use values:==================WARNING: DATA RACERead at 0x00c042030210 by goroutine 6:  runtime.convT2E()      Go/src/runtime/iface.go:155 +0x0  main.(*field).print()      .../m.go:14 +0x6cPrevious write at 0x00c042030210 by main goroutine:  main.main()      .../m.go:22 +0x1c3Goroutine 6 (running) created at:  main.main()      .../m.go:23 +0x204==================twothreethreeuse pointers:onetwothreeFound 1 data race(s)


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

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

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