【问题标题】:Non-blocking channel in gogo中的非阻塞通道
【发布时间】:2021-09-26 08:52:58
【问题描述】:

我有一些这样的代码:

go func(ch chan bool) chan bool {

    // some processing
    ch <- true
    return ch
}(ch)

for i := 0; i < TotalQuestions; i++ {
    // check if channel ch has some value
    // If it has then execute below statements, else break out of the loop


    fmt.Println(questions[i])
    answer, _ := InputReader.ReadString('\n')

    // some processing

}
fmt.Println("Your Total score is " + strconv.Itoa(TotalScore) + " out of " + strconv.Itoa(TotalQuestions))

现在我要做的是检查通道 ch 是否有值(在 for 循环中)。如果它有一个值,那么我想跳出 for 循环来打印最后一条语句。否则,我想继续我的循环。我试图插入选择块,但没有奏效(通道被阻塞并且代码没有打印问题)。该怎么做?

【问题讨论】:

  • 你为什么使用通道,为什么不能使用布尔变量之类的?如果你通过通道发送一些东西,一旦接收者收到它,它就不再存在了,你确定你想要这样,因为这样一个普通的布尔值就足够了。
  • 虽然这可以通过缓冲通道实现,但这样做存在固有的竞争。这是一种设计气味,很可能是XY problem。你不应该使用这样的频道,很可能你根本不应该使用频道来做你想做的事。你想达到什么目标?
  • 我想制作一个带有计时器的测验程序。当计时器到期或用户回答每个问题时,程序应停止并打印分数。在此期间,我尝试了学习渠道。
  • 选择语句可以解决问题。在一种情况下使用频道,另一种情况是测验的条件(所有问题都已回答)。这在一个(无限的)for循环中,只有在计时器完成或所有问题都得到回答时才会停止程序。
  • 该问题不适合该标题。该问题可能存在更好的示例,以便 Google 员工获得更好的帮助。

标签: go nonblocking channel goroutine


【解决方案1】:
package main
    
import (
    "fmt"
    "log"
    "math/rand"
    "time"
)

func main() {

    // user score, no.of questions asked so far
    var score, num int
    var correct bool // temporary variable to decide if the answer is right
    // questions
    var questions = make([]string, 13)

    t1 := time.Tick(time.Second * 7) // timer loop:
    for {
        select {
        case <-t1:
            log.Println("ran out of time")
            break loop
        default:
            // have any questions further questions to ask
            if num < len(questions) {

                // simulate typing
                time.Sleep(time.Millisecond * 777)

                // correct or wrong answer
                correct = (rand.Intn(777)%2 == 0)

                if correct {
                    fmt.Println("you did it")
                    score++ //increase score
                } else {
                    fmt.Println("try again")
                }

            } else {
                // no questions, state and break
                log.Println("all questions were finished")
                break loop //break loop, all questions were finished
            }
            num++
        }
    }

    //print final score
    fmt.Println("your score is:", score)
}

【讨论】:

    猜你喜欢
    • 2017-04-21
    • 2020-11-22
    • 2015-12-08
    • 2014-05-18
    • 2023-03-06
    • 2015-01-15
    • 1970-01-01
    • 1970-01-01
    • 2017-12-08
    相关资源
    最近更新 更多