It's clear I don't understand something about scoping. I've distilled the problem down to the following (run it at The Go Playground):
package main
import (
"log"
"time"
)
type mystruct struct {
mybool bool
}
func new() mystruct {
var ms mystruct
go func() {
for {
time.Sleep(time.Second/2)
log.Println("loop says:",ms.mybool)
}
}()
return ms
}
func (m *mystruct) switchIt() {
if m.mybool {
m.mybool = false
} else {
m.mybool = true
}
}
func main() {
thing := new()
time.Sleep(2 * time.Second)
thing.switchIt()
time.Sleep(2 * time.Second)
thing.switchIt()
time.Sleep(2 * time.Second)
thing.switchIt()
}
As it is now, the boolean is always false
from the perspective of the endless loop in new()
's anonymous function. I'm trying to change that value with switchIt()
while the loop runs.
Moving the boolean to a global variable gives the behavior I want (value changed from the loop's perspective), but I need the boolean to be part of the object because there will be several instantiations of the object.
I modified your code a bit, and now it works as your expectation.
package main
import (
"log"
"time"
)
type mystruct struct {
mybool bool
}
func newThing() *mystruct {
var ms mystruct
go func() {
for {
time.Sleep(time.Second / 2)
log.Println("loop says:", ms.mybool)
}
}()
return &ms
}
func (m *mystruct) switchIt() {
if m.mybool {
m.mybool = false
} else {
m.mybool = true
}
}
func main() {
thing := newThing()
time.Sleep(2 * time.Second)
thing.switchIt()
time.Sleep(2 * time.Second)
thing.switchIt()
time.Sleep(2 * time.Second)
thing.switchIt()
}
Issues of your code:
new()
to newThing()
, because it's confusing with the built-in new()
function.new()
returns a copy of the struct, thus after calling new()
, there are 2 copies of the struct, that's why you can never change it.Tips on go
:
struct
, when assign / pass as param / return from function, it always makes a copy.bool
is not a reference type, so can't use this.struct
, array
behavior similarly.slice
instead.slice
/ map
contain reference to underling data structure that hold the actual data.slice
, but they still refer to the same underling data structure (an array
).BTW, Effective go is a good place to pick up these tricky details about go :)