1

For the following code, It seems going into dead loop. After s, err := minusOne(s), s is shorten according the log info. But the before minus log shows that it never changed.

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
        }
    }
}

If I change it slightly like, it works like expected.

s1, err := minusOne(s)
s = s1

Or if I remove the err returning in the minusOne function, and it also works.

s = minusOne(s)

I really can't understand it. Anyone can help with it?

3 Answers 3

5

On each iteration you declare new variables called s and err:

s, err := minusOne(s)

Their scope is only the current iteration, so the above line keeps using the same s variable declared outside of the loop. From Declarations and scope part of The Go Specification:

Go is lexically scoped using blocks:

  1. 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.

To fix it, you need to use assignment:

var err error
for {
    // ...
    s, err = minusOne(s)
    // ...
}
Sign up to request clarification or add additional context in comments.

Comments

3

You are using the short var declaration :=. You must take care with this.

Inside the for loop you are creating two new variables, err, but also s (with a new scope inside the for loop). This wouldn't be a problem if you do in the same scope.

You can simply extract the err to a pre-declared variable before like that:

var err error
s, err = minusOne(s)

Comments

1

do not use s in the for loop, := will add a new local var. just rename the s in for loot to s1. You can also declare a outside for loop and replace := with =

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.