尝试 运行 单独 goroutine 中的函数时出现错误 "expected ';', found 'go'syntax"
Getting error "expected ';', found 'go'syntax" while trying to run a function in separate goroutine
这是我正在尝试编写的代码 ->
total ,err := go buildRepository.CountBuildScreenshots(buildId, OrgId, userID)
if err!=nil {
fmt.Println(err)
}
计数构建屏幕截图return一个整数和一个错误。
我的用例是我有多个构建,我想要 运行 此功能。该函数计算量大,单次构建需要 5 秒的计算时间。因此我想使用等待组。
for i := 0; i < len(builds); i++ {
buildId := builds[i].BuildId
buildRepository := NewBuildRepository(database.GetReadLTMSConn())
total ,err := go (buildRepository.CountBuildScreenshots(buildId, OrgId, userID))
if err!=nil {
fmt.Println(err)
}
(builds[i]).TotalScreenshots = total
}
我会将您的函数包装在一个 return 除了写入通道之外什么都不做的函数中。然后您可以从该频道读取并等待所有结果。
我正在将循环包装在另一个 goroutine 中,以便能够在所有写入完成后关闭通道。
type result struct {
Count int
Err error
}
func main() {
// the channel for the results
c := make(chan result)
// the top level goroutine waits for all
// spawned goroutines to be done and closes the channel
go func(c chan result) {
// waitgroup is used to wait
wg := &sync.WaitGroup{}
// kick of the long running functions concurrently
// in they own goroutine
for i := 0; i < 10; i++ {
wg.Add(1)
go func(c chan result) {
defer wg.Done()
total, err = count()
// write the results to the channel
c <- result{total, err}
}(c)
}
// wait until all are done
wg.Wait()
// important, close the channel
close(c)
}(c)
// range over the results as they are coming in
// until the channel is closed
for r := range c {
if r.Err != nil {
fmt.Println(r.Err)
} else {
fmt.Println(r.Count)
}
}
}
// simulate a longer running function
func count() (int, error) {
r := rand.Intn(10)
time.Sleep(time.Duration(r) * time.Second)
return 1, nil
}
go
关键字启动并发 goroutine。它不等待 goroutine 完成(运行ning concurrently 是 goroutine 的整个 point)因此它无法提供函数的 return 值.
您需要找到一种不同的方式来 returning 您的 goroutine 的结果。您还需要一个同步机制,以便您知道它何时完成。 Achannel
是标准解
如果您拥有 CountBuildScreenshots
的实现,您可以直接更改该函数。我假设您不拥有该实现,在这种情况下,我们将 CountBuildScreenshots
包装在另一个函数中以处理响应。我们还将创建一个结构来保存两个 return 值。
type countBuildScreenshotsResult struct {
total int
err error
}
现在我们可以创建一个可用于 return 该结构的通道。当我们准备好使用结果时,我们将在通道上等待。
results := make(chan countBuildScreenshotsResult)
现在我们可以调用我们的协程了:
go func() {
var result countBuildScreenshotsResult
result.total, result.err := buildRepository.CountBuildScreenshots(buildId, OrgId, userID)
results <- result
}()
稍后在代码中,我们从通道收集 goroutine 的结果:
res := <-results
if res.err != nil {
...
} else {
...
}
运行 只有当您在等待 CountBuildScreenshots
到 return 期间还有其他操作要完成时,此函数并发在其自己的 goroutine 中才有意义。如果您将立即等待结果,那么 运行ning 在 goroutine 中对您没有任何作用。只有当你同时有 other 操作 运行 时,goroutines 才有意义。换句话说,如果您最终得到如下代码:
results := make(chan Result)
go func() {
...
results <- result
}()
res := <- results
那么 goroutine 就没有意义了,你也可以 运行 同一个 goroutine 中的操作,因为它无论如何都会在完成时被阻塞。
这是我正在尝试编写的代码 ->
total ,err := go buildRepository.CountBuildScreenshots(buildId, OrgId, userID)
if err!=nil {
fmt.Println(err)
}
计数构建屏幕截图return一个整数和一个错误。
我的用例是我有多个构建,我想要 运行 此功能。该函数计算量大,单次构建需要 5 秒的计算时间。因此我想使用等待组。
for i := 0; i < len(builds); i++ {
buildId := builds[i].BuildId
buildRepository := NewBuildRepository(database.GetReadLTMSConn())
total ,err := go (buildRepository.CountBuildScreenshots(buildId, OrgId, userID))
if err!=nil {
fmt.Println(err)
}
(builds[i]).TotalScreenshots = total
}
我会将您的函数包装在一个 return 除了写入通道之外什么都不做的函数中。然后您可以从该频道读取并等待所有结果。
我正在将循环包装在另一个 goroutine 中,以便能够在所有写入完成后关闭通道。
type result struct {
Count int
Err error
}
func main() {
// the channel for the results
c := make(chan result)
// the top level goroutine waits for all
// spawned goroutines to be done and closes the channel
go func(c chan result) {
// waitgroup is used to wait
wg := &sync.WaitGroup{}
// kick of the long running functions concurrently
// in they own goroutine
for i := 0; i < 10; i++ {
wg.Add(1)
go func(c chan result) {
defer wg.Done()
total, err = count()
// write the results to the channel
c <- result{total, err}
}(c)
}
// wait until all are done
wg.Wait()
// important, close the channel
close(c)
}(c)
// range over the results as they are coming in
// until the channel is closed
for r := range c {
if r.Err != nil {
fmt.Println(r.Err)
} else {
fmt.Println(r.Count)
}
}
}
// simulate a longer running function
func count() (int, error) {
r := rand.Intn(10)
time.Sleep(time.Duration(r) * time.Second)
return 1, nil
}
go
关键字启动并发 goroutine。它不等待 goroutine 完成(运行ning concurrently 是 goroutine 的整个 point)因此它无法提供函数的 return 值.
您需要找到一种不同的方式来 returning 您的 goroutine 的结果。您还需要一个同步机制,以便您知道它何时完成。 Achannel
是标准解
如果您拥有 CountBuildScreenshots
的实现,您可以直接更改该函数。我假设您不拥有该实现,在这种情况下,我们将 CountBuildScreenshots
包装在另一个函数中以处理响应。我们还将创建一个结构来保存两个 return 值。
type countBuildScreenshotsResult struct {
total int
err error
}
现在我们可以创建一个可用于 return 该结构的通道。当我们准备好使用结果时,我们将在通道上等待。
results := make(chan countBuildScreenshotsResult)
现在我们可以调用我们的协程了:
go func() {
var result countBuildScreenshotsResult
result.total, result.err := buildRepository.CountBuildScreenshots(buildId, OrgId, userID)
results <- result
}()
稍后在代码中,我们从通道收集 goroutine 的结果:
res := <-results
if res.err != nil {
...
} else {
...
}
运行 只有当您在等待 CountBuildScreenshots
到 return 期间还有其他操作要完成时,此函数并发在其自己的 goroutine 中才有意义。如果您将立即等待结果,那么 运行ning 在 goroutine 中对您没有任何作用。只有当你同时有 other 操作 运行 时,goroutines 才有意义。换句话说,如果您最终得到如下代码:
results := make(chan Result)
go func() {
...
results <- result
}()
res := <- results
那么 goroutine 就没有意义了,你也可以 运行 同一个 goroutine 中的操作,因为它无论如何都会在完成时被阻塞。