gpt4 book ai didi

使用循环和线程的 Golang 对象范围

转载 作者:IT王子 更新时间:2023-10-29 02:01:35 25 4
gpt4 key购买 nike

很明显,我对范围界定一无所知。我已将问题归结为以下内容 ( 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()
}

现在,从 new() 的匿名函数中的无限循环的角度来看, bool 值始终为 false。我试图在循环运行时使用 switchIt() 更改该值。

将 bool 值移动到全局变量会产生我想要的行为(从循环的角度来看值已更改),但我需要 bool 值成为对象的一部分,因为对象将有多个实例化。

最佳答案

我稍微修改了你的代码,现在它按你的预期工作了。


代码

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,当赋值/作为参数传递/从函数返回时,它总是制作一个副本。
    你有 2 个选项来征服这个:
    • 改用指针。
      在这种情况下,只有一个结构副本。
    • 让结构中的字段为指针或类似的引用类型(例如 slice 或 map)
      在这种情况下,有 2 个结构副本,但这些字段引用相同的底层数据结构。
      但是在你的代码中,bool 不是引用类型,所以不能使用它。
  • 类似于structarray的行为也类似。
    尽管大多数时候,您只会使用 slice
  • 另一方面,slice/map 包含对保存实际数据的底层数据结构的引用。
    因此,如果您将一个 slice 分配给另一个 slice 变量,或者从一个函数返回它,将会有 2 个 slice,但它们仍然引用相同的底层数据结构 (一个 数组).
    因此,对一个 slice 所做的更改将对另一个 slice 可见。

顺便说一句,Effective go是获取有关 go 的这些棘手细节的好地方 :)

关于使用循环和线程的 Golang 对象范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51689131/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com