在Go语言中,是否有类似于while的赋值和比较操作?

huangapple go评论89阅读模式
英文:

Assign-and-compare in go's while-equivalent?

问题

在Go语言中,你可以这样做:

if foo := bar(); foo != nil {
    ...
}

在C/C++中,你可以这样做:

while ((foo = bar()) != NULL) {
    ...
}

然而,Go语言的语法似乎没有提供在while循环中进行赋值和比较的等效方式;Go语言用for特定的调用替代了while(例如for a等同于for ; a ;)。尝试使用if版本的语法会让解析器困惑,因为它期望有第三个语句。

我可以这样写:

for foo := bar(); foo != nil; foo = bar() {
    ....
}

但在这种情况下,bar()调用相当长、复杂,不容易拆分成自己的函数(虽然我可以声明一个本地的func来调用,但这仍然降低了代码的清晰度)。

目前我这样做:

for {
    foo := bar()
    if foo == nil {
        break
    }
    ...
}

但这看起来不够简洁,因为它将循环条件与循环语句本身分开,并且依赖于break

那么,在Go语言中有没有一种简洁、惯用的方式来在while循环中进行赋值和比较呢?这是一个如此常见的用例,我无法想象没有办法做到这一点。

英文:

In Go you can do:

if foo := bar() ; foo != nil {
    ...
}

In C/C++ you can do:

while ((foo = bar()) != NULL) {
    ...
}

However, Go's syntax does not seem to provide any equivalent way of doing assign-and-compare in a while loop; Go has replaced while with a specific invocation of for (e.g. for a is equivalent to for ; a ;). Simply trying to use the if version syntax confuses the parser, as it's expecting there to be a third statement.

I could just say:

for foo := bar() ; foo != nil ; foo = bar() {
    ....
}

but in this case, the bar() call is fairly long, complex, and not easy to break out into its own function (although I could do something like declaring a local func to call, but that still reduces the clarity of the code).

For now I am doing:

for {
    foo := bar();
    if foo == nil { break; }
    ...
}

but this seems unclean, both because it separates the loop criteria from the loop statement itself, and because it relies on break.

So, is there a clean, idiomatic way of doing an assign-and-compare in a while loop in Go? This is such a common use case I can't imagine that there's no way of doing it.

答案1

得分: 16

没有。Go语言没有while语句,只有for语句的特殊形式 - 而赋值是一个语句,而不是一个表达式。你的例子在我看来是符合Go语言习惯的。

英文:

No. Go has no while statement, only the special form of the for statement - and assignment is a statement, not an expression. Your examples are IMHO idiomatic Go.

答案2

得分: 0

你可以创建一个迭代器,类似于bufio#Scanner.Scan

package main

type bar struct { foo int }

func (b *bar) next() bool {
   b.foo++
   return b.foo < 10
}

func main() {
   var b bar
   for b.next() {
      println(b.foo)
   }
}

然后在Next函数中,你可以放入所有你需要的复杂逻辑。

英文:

You can create an iterator, similar to bufio#Scanner.Scan:

package main

type bar struct { foo int }

func (b *bar) next() bool {
   b.foo++
   return b.foo &lt; 10
}

func main() {
   var b bar
   for b.next() {
      println(b.foo)
   }
}

Then in the Next function, you can put all the complicated logic you need.

huangapple
  • 本文由 发表于 2012年10月30日 02:56:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/13127929.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定