我有一个在轮询时返回值的函数,但是在某些时候它将停止返回明智的值,如下所示。
有没有比每次检查if !ok
更为惯用的方式对其进行轮询。我在想类似于使用range
轮询 channel 的方法。
package main
import "fmt"
func iter() func() (int, bool) {
i := 0
return func() (int, bool) {
if i < 10 {
i++
return i, true
}
return i, false
}
}
func main() {
f := iter()
for {
v, ok := f()
if !ok {
break
}
fmt.Println(v)
}
}
最佳答案
我认为没有办法避免检查正常,但是您可以对其进行重组,以免出现难看的中断:
for v,ok := f(); ok; v,ok = f() {
fmt.Println(v)
}
应当指出,这仅在以下情况下有效:
不幸的是Go不会让您做类似的事情
f := iter()
g := iter()
v,ok,v2,ok2 := f(), g(); ok && ok2; v,ok,v2,ok2 := f(), g() {
// code
}
因此,如果您的案例包含多个函数,那么除非它们仅返回一个值,否则它们会陷入ifs和break的困境。
也就是说,(在反射时),在Go中编写迭代器的更惯用的方法是遍及整个 channel 。考虑等效程序:
func Iterator(iterCh chan<- int) {
for i := 0; i < 10; i++ {
iterCh <- i
}
close(iterCh)
}
func main() {
iter := make(chan int)
go Iterator(iter)
for v := range iter {
fmt.Println(v)
}
}
在这种情况下,不要返回 bool 值,而只要发送完值就关闭 channel 。此方法的缺点是,如果要返回多个值,则必须制作某种结构以通过 channel 发送。
最后,如果您想对其进行包装,以在每次运行迭代器时隐藏 channel 样板:
func Iter() <-chan int {
iterChan := make(chan int)
go iter(iterChan)
return iterChan
}
func iter(iterCh chan<- int) {
for i := 0; i < 10; i++ {
iterCh <- i
}
close(iterCh)
}
func main() {
for v := range Iter() {
fmt.Println(v)
}
}
这是用于初始实现的更多代码,但是省去了每次要使用迭代器时都必须手动声明 channel 的麻烦。
关于go - 轮询功能的惯用方式,直到确定!= true,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17867305/