【问题标题】:Polling a simple queue from within another, and filling the first queue from the second queue从另一个队列中轮询一个简单队列,并从第二个队列填充第一个队列
【发布时间】:2017-09-01 22:00:42
【问题描述】:

换句话说,事件驱动队列的流程:

  • 轮询事件队列
  • 如果找到事件,处理事件,然后下一个轮询周期
  • 如果未找到事件,则轮询数据队列
  • 如果找到数据,推送到事件队列,开始下一轮轮询事件队列
  • 如果没有找到数据,退出流程

代码如下:

package main

import "fmt"

type Queue struct {
    stream []string
}

// Next returns first element from stream.
// Returns false if no element is in the stream.
func (q *Queue) Next() (s string, ok bool) {
    if len(q.stream) == 0 {
        return s, false
    }
    s = q.stream[0]
    q.stream = q.stream[1:]
    return s, true
}

func main() {
    // define queues
    events := []string{"event"}
    q1 := &Queue{stream: events}
    data := []string{"data1", "data2", "data3"}
    q2 := &Queue{stream: data}

    // poll first queue
    for e, ok := q1.Next(); ok; e, ok = q1.Next() {
        // nothing in q1
        if !ok {
            fmt.Println("Nothing found in q1")

            // poll second queue
            d, ok := q2.Next()
            if !ok {
                return
            }

            // found d in q2 and append to q1
            fmt.Printf("found in q2 %v\n", d)
            q1.stream = append(q1.stream, d)
            return
        }

        // do some stuff to e ...
        fmt.Printf("found in q1 %v %v\n", e, ok)
    }
}

在操场上试试https://play.golang.org/p/bgJzq2hCfl

我得到的只是第一个队列中的元素。

found in q1 event true

代码从不轮询第二个队列并将其元素附加到第一个队列。我怎么了?

如果我尝试

// poll first queue
for e, ok := q1.Next() {
    // ...
}

编译器抛出

tmp/sandbox299553905/main.go:28:25: syntax error: e, ok := q1.Next() used as value

任何提示表示赞赏。


更新:这是循环的解决方案。

// poll first queue
for e, ok := q1.Next(); true; e, ok = q1.Next() {
    // nothing in q1
    if !ok {
        fmt.Println("Nothing found in q1")

        // poll second queue
        for d, ok := q2.Next(); true; d, ok = q2.Next() {
            if !ok {
                fmt.Println("Nothing found in q2. exit")
                return
            }

            // found d in q2 and append to q1
            fmt.Printf("found in q2: %v. append to q1\n", d)
            q1.stream = append(q1.stream, d)
            break
        }
        continue
    }

    // do some stuff to e ...
    fmt.Printf("found in q1: %v. do stuff\n", e)
}

你可以在操场上测试它https://play.golang.org/p/qo0zoBPROe

【问题讨论】:

    标签: go queue


    【解决方案1】:

    当它没有找到任何东西时,你退出循环。只需将您的 for 循环更改为以下内容,但请注意,这会使循环无限,因此您必须 breakreturn 才能退出。

    for e, ok := q1.Next(); ok || !ok ; e, ok = q1.Next() {
    

    【讨论】:

    • 就是这样。谢谢你。我将在我的问题中更新最终解决方案..
    • @dirk 仅仅标记一个答案就足够了。你不应该用答案来编辑问题。
    【解决方案2】:

    在第一次迭代之后,“增量”发生,这次ok 设置为false。下一步比较ok == true(循环终止条件),情况并非如此,因此退出。

    现在,如果我正确理解您的尝试,我会将循环修改为:

    // poll first queue
    for e, ok := q1.Next(); true; e, ok = q1.Next() {
        // nothing in q1
        if !ok {
            fmt.Println("Nothing found in q1")
    
            // poll second queue
            d, do := q2.Next()
            if !do {
                break
            }
    
            // found d in q2 and append to q1
            fmt.Printf("found in q2 %v\n", d)
            q1.stream = append(q1.stream, d)
        } else {
    
            // do some stuff to e ...
            fmt.Printf("found in q1 '%v' ok=%v\n", e, ok)
        }
    }
    

    【讨论】:

    • 啊,是的,只是把true 放在那里比我在回答中所做的要好,但作为一个单一的答案,我想确保 var ok 会被使用而不是抛出编译器错误。干杯!编辑:我想它无论如何都会被使用,因为它在循环中被重新分配,所以true 胜出很多。
    • 谢谢。我从您的解决方案中获取了ˋtrueˋ。但是@RayfenWindspear 更快...
    • @dirk :) 不用担心
    猜你喜欢
    • 1970-01-01
    • 2014-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-06
    • 1970-01-01
    • 1970-01-01
    • 2013-11-12
    相关资源
    最近更新 更多