【问题标题】:Assign-and-compare in go's while-equivalent?在 go 的 while-equivalent 中分配和比较?
【发布时间】:2021-05-22 23:03:23
【问题描述】:

在 Go 中你可以这样做:

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

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

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

但是,Go 的语法似乎没有提供任何等效的方法来在 while 循环中进行分配和比较; Go 已将 while 替换为 for 的特定调用(例如,for a 等同于 for ; a ;)。简单地尝试使用if 版本的语法会使解析器感到困惑,因为它预计会有第三条语句。

我只能说:

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

但在这种情况下,bar() 调用相当长、复杂,并且不容易分解成它自己的函数(虽然我可以做一些事情,比如声明一个本地的 func 来调用,但这仍然会减少代码清晰)。

现在我正在做:

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

但这似乎不干净,因为它将循环条件与循环语句本身分开,并且因为它依赖于break

那么,在 Go 的 while 循环中是否有一种干净、惯用的方式来进行分配和比较?这是一个如此常见的用例,我无法想象没有办法做到这一点。

【问题讨论】:

    标签: go


    【解决方案1】:

    没有。 Go 没有 while 语句,只有 for 语句的特殊形式——赋值是语句,而不是表达式。你的例子是恕我直言惯用的围棋。

    【讨论】:

      【解决方案2】:

      你可以创建一个迭代器,类似于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函数中,你可以把你需要的所有复杂的逻辑都放进去。

      【讨论】:

      • 这似乎只是 for foo := bar(); foo; foo := bar() 方法的一种更复杂的形式,当时也不可行(因为 bar() 特别不能分解成自己的函数)。
      猜你喜欢
      • 2013-12-01
      • 2015-01-04
      • 1970-01-01
      • 2016-03-20
      • 1970-01-01
      • 2012-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多