【问题标题】:Go language - running the same code for multiple select casesGo 语言 - 为多个选择案例运行相同的代码
【发布时间】:2016-09-23 17:18:25
【问题描述】:

假设我们有多个通知源(通道),并且我们希望对其中一些通知事件执行一些类似的任务。例如,考虑我们每 10 分钟调用一次doSomething() 以及根据用户请求的情况。 Go 中可能的实现可能是这样的:

var ticker = time.NewTicker(10*time.Minute)
nowDoSomething := make(chan time.Time, 1)
for {
    select {
    case <-ticker.C:
        nowDoSomething<-time.Now()

    case <-userReq: // some channel activated occasionally 
        nowDoSomething<-time.Now()

    case <-nowDoSomething:
        doSomething()
    }
}

还有什么其他的、或许更好的方法可以实现类似的功能?

【问题讨论】:

  • go fmt是你最好的朋友,请使用它。

标签: select go channel


【解决方案1】:

也许您可以使用反射包中的 Select 函数来做到这一点:

func Select(cases []SelectCase) (选择 int, recv Value, recvOK bool)

【讨论】:

    【解决方案2】:

    如果您可以调用 doSomething(),为什么还要使用通道向自己发送信号?我知道 doSomething 可能不完全是一个函数,但您始终可以使用本地闭包。

    查看一个工作示例:

    package main
    
    import (
        "fmt"
        "time"
    )
    
    
    
    func someRoutine (userReq chan int) {
        doSomething := func () {
            fmt.Printf ("OK %v\n", time.Now())
        }
    
      var ticker = time.NewTicker(10*time.Second)
      for {
        select {
        case <-ticker.C:
            doSomething()
        case <-userReq: // some channel activated occasionally 
            doSomething()
        }
      }
    }
    
    func main() {
        userReq := make(chan int, 1)
        go someRoutine(userReq);
    
        userReq <- 1 // user requested some action here (just to mark the start)
        time.Sleep(15*time.Second)
        userReq <- 1 // user requested some action here
    
        time.Sleep(30*time.Second)// Put your own waiting and exiting logic here
    }
    

    如果您仍想在这个简单的修正之外对其进行优化,总有一些替代方案可用。但是只有两个通道可供读取,请确保您没有进行过早的优化。

    【讨论】:

    • Go 语法不喜欢那样。你会得到这个错误“选择案例不能是列表”
    猜你喜欢
    • 2016-04-13
    • 2021-05-15
    • 2015-10-18
    • 1970-01-01
    • 2014-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多