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

Does goroutine create a deep copy or shallow copy?

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 睡眠 10 秒,那么当 main 函数在 10 秒内改变 "myTest" 的值时,goroutine 会做什么?

go中没有"deep copy"的概念,一切都是传值

在您的实例中,这不是副本,您直接引用变量,如果您想要副本,请执行以下操作:

myTest := myTest
time.Sleep(10 * time.Second)
fmt.Println(myTest.name)

go中没有"deep copy"的概念,一切都是传值
没有你的样本甚至不是浅拷贝你传递了一个指针(字符串地址):
如果您在 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()
}

因此,正如您在此示例中看到的,主函数中的字符串 name 内容更改反映到 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()
}

并查看: