2

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

fluter
  • 13,238
  • 8
  • 62
  • 100
poopoothegorilla
  • 764
  • 7
  • 13

2 Answers2

2

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.

eduncan911
  • 17,165
  • 13
  • 68
  • 104
  • Named return values are, just like labels, very useful when you need them, but you almost never do. – Filip Haglund May 10 '16 at 12:19
  • correct. but I see a lot of code in projects where people make it the standard. and Go's blog recommends not using them except in exceptional cases that allow the code to be easier read (which often times means not). – eduncan911 May 10 '16 at 12:19
  • 1
    I pretty much only use named return values when I need to modify a return value in a defered function. "Deferred functions may read and assign to the returning function's named return values." https://blog.golang.org/defer-panic-and-recover – Filip Haglund May 10 '16 at 12:22
  • +1 good point, using `defer` to modify the named parameter. i think there was a Go Tour for that very thing. – eduncan911 May 10 '16 at 13:22
0

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?

Community
  • 1
  • 1