对于下面的代码,似乎进入了死循环。
在s, err := minusOne(s)
之后,s根据日志信息缩短。
但是减去之前的日志显示它从未改变。
func minusOne(s string) (string, error) {
if len(s) >= 0 {
return s[1:], nil
}
return "", nil
}
func TestStr(t *testing.T) {
s := "hello world"
for {
log.Println("before minus", s)
s, err := minusOne(s)
log.Println("after minus", s)
if err == nil && len(s) == 0 {
break
}
}
}
如果我稍微改变一下,它就会像预期的那样工作。
s1, err := minusOne(s)
s = s1
或者如果我删除 minusOne 函数中返回的错误,它也可以工作。
s = minusOne(s)
我实在是看不懂。 任何人都可以帮忙吗?
最佳答案
在每次迭代中,您声明名为 s
和 err
的新变量:
s, err := minusOne(s)
它们的作用域只是当前迭代,所以上面这行代码继续使用在循环外声明的相同 s
变量。来自 Declarations and scope Go 规范的一部分:
Go is lexically scoped using blocks:
- The scope of a constant or variable identifier declared inside a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl for short variable declarations) and ends at the end of the innermost containing block.
要修复它,您需要使用赋值:
var err error
for {
// ...
s, err = minusOne(s)
// ...
}
关于string - 奇怪的行为,同时变量与函数的输入和输出相同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50075996/