I'm not 100% sure what you mean by "copy made atomically" means in this 
context. But if you mean is calling a value receiver method safe for 
concurrently, then the answer is no. 

In fact it can be the source of subtle races. Take for example this simple 
program (https://play.golang.org/p/Wk5LHxEJ8dQ): 

package main
import "fmt"

type Split struct {
    MutValue  uint64
    CostValue uint64
}

func (s Split) GetConstValue() uint64 {
    return s.CostValue
}

var Sum uint64

func main() {
    theOne := Split{7, 3}
    fmt.Print("Start ")

    go func() {
        for {
            theOne.MutValue += 1
        }
    }()

    for {
        Sum += theOne.GetConstValue()
    }
}

If you run this with the race detector on, you will see that there is a 
race between " theOne.MutValue += 1" and "Sum += theOne.GetConstValue()". 
At first glance it might seem like this should be ok, since the body of 
GetConstValue() only reads a non-changing variable, and does not touch MutValue 
. But in fact calling the function does a copy, and so also reads "MutValue", 
which is being concurrently modified, hence the race.  

If GetConstValue() is changed to take a pointer receiver, then the race 
goes away.   

On Tuesday, June 8, 2021 at 6:08:56 AM UTC-4 Ian Davis wrote:

> This question came to me while reading the recent thread titled "Knowing 
> from documentation whether an interface is holding a pointer or a struct?"
>
> When a method with a non-pointer receiver is called, is the copy made 
> atomically? My intuition says it must be but perhaps someone else can 
> confirm it?
>
> If so, how does it work? 
>
> Ian
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/a2ebc1d7-0a3e-4a70-a4a0-ab88fd675d34n%40googlegroups.com.

Reply via email to