Does goroutine create a deep copy or shallow copy?

Issue

var person struct {
    name string
    id   int
    phone int
}

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


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

Does the goroutine deep copy the variable “myTest” from main function?

If my goroutine like this:

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

This goroutine sleep 10 seconds, so when the main function change the value of “myTest” during 10 seconds, what will goroutine do?

Solution

There’s no concept of “deep copy” in go, everything is passed by value.
no your sample even is not a shallow copy you passed a pointer (address of string):
if you change myTest.name in main function then you print it again after that change you will see it will change, see this proving sample code:

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()
}

first define person struct like this:

type person struct {
    name  string
    id    int
    phone int
}  

second use sync.WaitGroup to wait for goroutine to finish.

and about your main question, you can test it yourself like this:

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()
}

so as you see in this sample the string name content change in the main function reflected to goroutine, so it is not a copy.
if you need copy call like this:

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()
}

and see: Is it correct to ref a var inside golang func?

Answered By – user6169399

Answer Checked By – David Goodson (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.