在if块中确定变量范围的优势

Is there an advantage to scoping the second err in an if statement after an err has already been created in the scope of foo()? Especially in terms of memory management or being idiomatic.

Version 1

func foo() {
    temp, err := something()
    if err != nil {
        ...
    }

    if err := other(); err != nil {
        ...
    }
}

Version 2

func foo() {
    temp, err := something()
    if err != nil {
        ...
    }

    err = other()
    if err != nil {
        ...
    }
}

https://golang.org/doc/effective_go.html#control-structures

Remember, error is an interface. And nil interfaces are zero-length in bytes (and empty structs are zero-length too).

This means there is no additional work for the GC to cleanup either way.

It is a personal preference, and there's even a third way using named return values:

func foo() (err error) {
    ...
}

Though I highly recommend not using that pattern.

Personally, I prefer the idiomatic nature of inline with the if when I can and really enjoy when the pattern allows me to use it. But remember, the scoping of other variables are only available within the if:

if temp, err := other(); err != nil {
    // can only use temp here
    ...
}

(unless you define the vars ahead of time, which defeats the purpose of inlining anyways)

But most often, I need to keep temp around after the evaluation:

temp, err := something()
if err != nil {
    ...
}
// continue to use temp

Which means most of my code looks like the above.

But when I run across a pattern that allows it, you bet I'll use it. For example, bufio's Writer.WriteByte:

if err := writer.WriteByte(b); err != nil {
    ...
}

Where writer and b were defined in the outer scope, most likely with their own err checks. There is zero point of defining err outside the scope of the evaluation.

Limiting the scope of the err value just seems like the idiomatic way, when you can use it.

Advantage of scoping variables:

  • Since it cannot be accessed from other scope, Data Integrity is preserved.
  • Only required data can be passed to function , thus protecting the remaining data

see this:
Where can we use Variable Scoping and Shadowing in Go?