gpt4 book ai didi

go - goroutine创建的是深拷贝还是浅拷贝?

转载 作者:IT王子 更新时间:2023-10-29 01:26:51 25 4
gpt4 key购买 nike

var person struct {
name string
id int
phone int
}

func main () {
var myTest person
//construct the variable
...


go func() {
fmt.Println(myTest.name)
}()
}

goroutine 是否从 main 函数深度复制变量“myTest”?

如果我的 goroutine 是这样的:

go func() {
time.Sleep(10 * time.Second)
fmt.Println(myTest.name)
}

这个 goroutine sleep 10 秒,那么当 main 函数在 10 秒内改变“myTest”的值时,goroutine 会做什么?

最佳答案

go没有“深拷贝”的概念,一切都是按值传递。
你的样本甚至不是浅拷贝你传递了一个指针(字符串地址):
如果您在 main 函数中更改 myTest.name 然后在更改后再次打印它,您会看到它会发生变化,请参阅此证明示例代码:

package main

import (
"fmt"
"sync"
"time"
)

type person struct {
name string
id int
phone int
}

var wg sync.WaitGroup

func main() {
myTest := person{"Alex", 22, 123}
fmt.Printf("%T : %[1]v %v\n", myTest.name, &myTest.name) // string : Alex 0xc042006740
wg.Add(1)
go func() {
fmt.Printf("%T : %[1]v %v\n", myTest.name, &myTest.name) // string : Alex 0xc042006740
time.Sleep(500 * time.Millisecond)
fmt.Printf("%T : %[1]v %v\n", myTest.name, &myTest.name) // string : J 0xc042006740
wg.Done()
}()
time.Sleep(100 * time.Millisecond)
myTest.name = "J"
wg.Wait()
}

首先像这样定义person struct:

type person struct {
name string
id int
phone int
}

第二次使用 sync.WaitGroup 等待 goroutine 完成。

关于你的主要问题,你可以这样自己测试:

package main

import (
"fmt"
"sync"
"time"
)

type person struct {
name string
id int
phone int
}

var wg sync.WaitGroup

func main() {
myTest := person{"Alex", 22, 123}
wg.Add(1)
go func() {
fmt.Printf("%T : %[1]v\n", myTest.name) // string : Alex
time.Sleep(500 * time.Millisecond)
fmt.Printf("%T : %[1]v\n", myTest.name) // string : J
wg.Done()
}()
time.Sleep(100 * time.Millisecond)
myTest.name = "J"
wg.Wait()
}

因此,正如您在此示例中看到的,main 函数中的字符串 name 内容更改反射(reflect)到 goroutine,因此它不是副本。
如果您需要这样的复制调用:

package main

import (
"fmt"
"sync"
"time"
)

type person struct {
name string
id int
phone int
}

var wg sync.WaitGroup

func main() {
myTest := person{"Alex", 22, 123}
wg.Add(1)
go func(name string) {
fmt.Printf("%T : %[1]v\n", name) // string : Alex
time.Sleep(500 * time.Millisecond)
fmt.Printf("%T : %[1]v\n", name) // string : Alex
wg.Done()
}(myTest.name)
time.Sleep(100 * time.Millisecond)
myTest.name = "J"
wg.Wait()
}

并查看:Is it correct to ref a var inside golang func?

关于go - goroutine创建的是深拷贝还是浅拷贝?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37983977/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com