英文:
Polling a simple queue from within another, and filling the first queue from the second queue
问题
换句话说,事件驱动队列的流程如下:
- 轮询事件队列
- 如果找到事件,则处理事件,然后进行下一次轮询
- 如果未找到事件,则轮询数据队列
- 如果找到数据,则将其推送到事件队列,并开始下一次轮询事件队列
- 如果未找到数据,则退出流程
以下是代码:
package main
import "fmt"
type Queue struct {
stream []string
}
// Next 从流中返回第一个元素。
// 如果流中没有元素,则返回 false。
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() {
// 定义队列
events := []string{"event"}
q1 := &Queue{stream: events}
data := []string{"data1", "data2", "data3"}
q2 := &Queue{stream: data}
// 轮询第一个队列
for e, ok := q1.Next(); ok; e, ok = q1.Next() {
// q1 中没有内容
if !ok {
fmt.Println("在 q1 中未找到任何内容")
// 轮询第二个队列
d, ok := q2.Next()
if !ok {
return
}
// 在 q2 中找到 d 并添加到 q1
fmt.Printf("在 q2 中找到:%v\n", d)
q1.stream = append(q1.stream, d)
return
}
// 对 e 进行一些操作...
fmt.Printf("在 q1 中找到:%v %v\n", e, ok)
}
}
在这段代码中,我只得到了第一个队列中的元素:
在 q1 中找到:event true
代码从未轮询第二个队列并将其元素添加到第一个队列中。我做错了什么?
如果我尝试:
// 轮询第一个队列
for e, ok := q1.Next() {
// ...
}
编译器会报错:
tmp/sandbox299553905/main.go:28:25: 语法错误:e, ok := q1.Next() 用作值
请给予一些建议,谢谢。
更新: 这里是循环的解决方案。
// 轮询第一个队列
for e, ok := q1.Next(); true; e, ok = q1.Next() {
// q1 中没有内容
if !ok {
fmt.Println("在 q1 中未找到任何内容")
// 轮询第二个队列
for d, ok := q2.Next(); true; d, ok = q2.Next() {
if !ok {
fmt.Println("在 q2 中未找到任何内容。退出")
return
}
// 在 q2 中找到 d 并添加到 q1
fmt.Printf("在 q2 中找到:%v。添加到 q1\n", d)
q1.stream = append(q1.stream, d)
break
}
continue
}
// 对 e 进行一些操作...
fmt.Printf("在 q1 中找到:%v。进行操作\n", e)
}
你可以在 playground 中测试它:https://play.golang.org/p/qo0zoBPROe。
英文:
In other words, the flow of an event-driven queue:
- poll event queue
- if event found, process event, then next poll cycle
- if no event found, poll data queue
- if data found, push to event queue, start next cycle polling event queue
- if no data found, exit flow
Here is the code:
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)
}
}
Try it in the playground https://play.golang.org/p/bgJzq2hCfl.
All I get is the element in the first queue.
found in q1 event true
The code never polls the second queue and append its elements to the first queue. What do i wrong?
If I try
// poll first queue
for e, ok := q1.Next() {
// ...
}
the compiler throws
tmp/sandbox299553905/main.go:28:25: syntax error: e, ok := q1.Next() used as value
Any hints appreciated.
Update: Here is the solution to the loop.
// 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)
}
You can test it in the playground https://play.golang.org/p/qo0zoBPROe.
答案1
得分: 2
当它找不到任何内容时,你退出循环。只需将你的for循环更改为以下形式,但请注意,这将使循环无限进行,所以你必须使用break
或return
来跳出循环。
for e, ok := q1.Next(); ok || !ok ; e, ok = q1.Next() {
英文:
You exit the loop when it doesn't find anything. Just change your for loop to the following, but note that this makes the loop infinite, so you have to break
out or return
to get out.
for e, ok := q1.Next(); ok || !ok ; e, ok = q1.Next() {
答案2
得分: 2
在第一次迭代之后,“increment”发生,这次将ok
设置为false
。下一步比较ok == true
(循环终止条件),这不成立,因此退出。
现在,如果我正确理解你的意图,我会修改循环为:
// 首先轮询第一个队列
for e, ok := q1.Next(); true; e, ok = q1.Next() {
// q1中没有内容
if !ok {
fmt.Println("在q1中未找到任何内容")
// 轮询第二个队列
d, do := q2.Next()
if !do {
break
}
// 在q2中找到d并添加到q1
fmt.Printf("在q2中找到 %v\n", d)
q1.stream = append(q1.stream, d)
} else {
// 对e进行一些操作...
fmt.Printf("在q1中找到 '%v' ok=%v\n", e, ok)
}
}
英文:
After the first iteration, the "increment" happens and this time ok
is set to false
. The next step compares ok == true
(loop termination condition) which is not the case and thus exits.
Now, if I understand correctly what you try to do, I would modify the loop to:
// 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)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论