Golang, running for range loop on channel, how to continue execution of block having received next value from channel?

huangapple go评论117阅读模式
英文:

Golang, running for range loop on channel, how to continue execution of block having received next value from channel?

问题

我正在学习Golang,现在遇到了一个问题。假设我有一个整数类型的通道:
ints = make(chan int)
我会在一段时间后不断接收值。所以我在通道上运行了一个for循环:

for update := range ints {
    if update > 10 { // 假设update == 15
         // 在这里,我想要继续执行这个代码块,但是希望
         // update变量能够得到下一个值,即使它小于等于10。
         // 假设下一个值是5。
         fmt.Println(update) // 所以这里应该打印"5",而不是"10"
         continue
    } else {
         fmt.Println("小于10")
         continue
    }
}

所以基本上我想要这个代码块在接收到下一个值之前暂停一段时间,然后继续执行,假设update变量现在有不同的值。

我的第一个想法是创建一个名为"isNewValueReceived"的布尔变量,并在需要的时候使用它来继续执行。然而,这似乎是错误的解决方案,因为程序的逻辑可能会变得更加复杂。

请帮助我找到这个问题的解决方案。非常感谢!

更新:

hasGoneAbove := false // 初始值为false,因为还没有接收到任何值
hasGoneAbove2 := false
hasGoneAbove3 := false
hasGoneAbove3 := false
for update := range ints {
    if hasGoneAbove{
      doSomeJob()
      hasGoneAbove = false
      hasGoneAbove2 = true
      continue
    }
    if hasGoneAbove2{
      doSomeJob2()
      hasGoneAbove2 = false
      hasGoneAbove3 = true
      continue
    }
    if hasGoneAbove3{
      doSomeJob3()
      hasGoneAbove3 = false
      continue
    }
    if update > 10 { 
         hasGoneAbove = true
    } else {
         fmt.Println("小于10")
    }
}
英文:

I'm studying Golang and now I'm stuck with a such situation.
Let's say I have a channel on ints:
ints = make(chan int)
And I keep receiving values after some period of time. So I'm running for range loop on my channel:

for update := range ints {
    if update > 10 { // let's say update == 15 for example
         // Here I want to continue execution of this block, however having
         // the next value of update var, even though it will be <= 10. 
         // lets say next value is received and update == 5.
         fmt.Println(update) // So this should print "5", not "10"
         continue
    } else {
         fmt.Println("less than 10")
         continue
    }
}

So basically I want this block to sleep for some time until next value is received from channel and continue execution, given that update variable now has different value.

My first thoughts were to create smth like "isNewValueReceived" bool variable and use it to continue execution where I want. However, it seems to be wrong solution, since the logic of the program might get more complex.

Please, help me to find a solution of this problem. Thank you in advance!

UPD:

hasGoneAbove := false // initially set to false as no values have been received
hasGoneAbove2 := false
hasGoneAbove3 := false
hasGoneAbove3 := false
for update := range ints {
    if hasGoneAbove{
      doSomeJob()
      hasGoneAbove = false
      hasGoneAbove2 = true
      continue
    }
    if hasGoneAbove2{
      doSomeJob2()
      hasGoneAbove2 = false
      hasGoneAbove3 = true
      continue
    }
    if hasGoneAbove3{
      doSomeJob3()
      hasGoneAbove3 = false
      continue
    }
    if update > 10 { 
         hasGoneAbove = true
    } else {
         fmt.Println("less than 10")
    }
}

答案1

得分: 1

尝试理解你的问题,你似乎想要使用一个状态跟踪变量:

hasGoneAbove := false // 初始设置为 false,因为还没有收到任何值
for update := range ints {
    if hasGoneAbove {
      fmt.Println(update)
      hasGoneAbove = false
    }
    if update > 10 { 
         hasGoneAbove = true
    } else {
         fmt.Println("小于10")
    }
}

更新后的代码,只保留最后一个值在内存中:

var lastValue int // 使用零值
for update := range ints {
    if lastValue > 2 {
      doSomeJob2()
    }
    if hasGoneAbove > 3 {
      doSomeJob3()
    }
    if lastValue > 10 {
      doSomeJob()
    } else {
       fmt.Println("小于10")
    }
    lastValue = update
}

注意:根据你问题中的代码,如果 lastValue10,那么这三个函数都会执行。根据它们的计算强度,你可能想要在 goroutine 中运行它们。

英文:

Trying to make sense of your question, you seem to want to work with a state tracking variable:

hasGoneAbove := false // initially set to false as no values have been received
for update := range ints {
    if hasGoneAbove{
      fmt.Println(update)
      hasGoneAbove = false
    }
    if update > 10 { 
         hasGoneAbove = true
    } else {
         fmt.Println("less than 10")
    }
}

Updated:
With this sort of holding only the last value in memory:

var lastValue int // use zero value
for update := range ints {
    if lastValue > 2{
      doSomeJob2()
    }
    if hasGoneAbove > 3{
      doSomeJob3()
    }
    if lastValue > 10{
      doSomeJob()
    } else {
       fmt.Println("less than 10")
    }
    lastValue = update
}

Note: as per the code in your question, if the LastValue is 10 then all three functions are going to execute. Depending on how compute intensive they are you might want to run them in a goroutine.

huangapple
  • 本文由 发表于 2022年4月27日 03:10:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/72019318.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定