很明显,我对范围界定不了解。我已将问题简化为以下(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()
}
现在,从false
匿名函数中的无限循环的角度来看,布尔值始终为new()
。我正在尝试在循环运行时使用switchIt()
更改该值。
将布尔值移动到全局变量可以实现我想要的行为(从循环的角度更改值),但是我需要布尔值成为对象的一部分,因为该对象将有多个实例化。
答案 0 :(得分:2)
我稍微修改了您的代码,现在它可以按您的期望工作了。
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()
}
您的代码问题:
new()
更改为newThing()
,因为它与内置的new()
函数混淆。new()
返回该结构的副本,因此在调用new()
之后,有2个该结构的副本,这就是您永远无法更改它的原因。 go
上的提示:
struct
,当赋值/作为参数传递/从函数返回时,它始终会复制。bool
不是引用类型,因此不能使用它。struct
和array
的行为。slice
。slice
/ map
包含对保存实际数据的基础数据结构的引用。slice
,但是它们仍然引用相同的基础数据结构(一个array
) 。顺便说一句,Effective go是了解go的这些棘手细节的好地方:)