goroutine 是创建深拷贝还是浅拷贝?

var person struct {

    name string

    id   int

    phone int

}


func main () {

    var myTest person

    //construct the variable 

    ...



    go func() {

        fmt.Println(myTest.name)

    }()

}

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


如果我的 goroutine 是这样的:


go func() {

    time.Sleep(10 * time.Second)

    fmt.Println(myTest.name)

}

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


森林海
浏览 173回答 2
2回答

MYYA

Go 中没有“深拷贝”的概念,一切都是按值传递的。不,你的样本甚至不是一个浅拷贝你传递了一个指针(字符串的地址):如果你改变myTest.name了main函数,那么你在改变之后再次打印它,你会看到它会改变,请看这个证明示例代码:package mainimport (    "fmt"    "sync"    "time")type person struct {    name  string    id    int    phone int}var wg sync.WaitGroupfunc 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 mainimport (    "fmt"    "sync"    "time")type person struct {    name  string    id    int    phone int}var wg sync.WaitGroupfunc 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()}因此,正如您在此示例中看到的name,主函数中的字符串内容更改反映到 goroutine,因此它不是副本。如果您需要这样的复制调用:package mainimport (    "fmt"    "sync"    "time")type person struct {    name  string    id    int    phone int}var wg sync.WaitGroupfunc 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()}

沧海一幻觉

Go 中没有“深拷贝”的概念,一切都是按值传递的。在您的实例中,这不是副本,您直接引用变量,如果您想要副本执行以下操作:myTest := myTesttime.Sleep(10 * time.Second)fmt.Println(myTest.name)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go