英文:
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 < 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论