I use golang 1.5.
I use the gopkg.in/rana/ora.v3 library to connect to Oracle.

In the example of Working With The Oracle Package Directly, there is an implementation of using the Oracle environment resource:

env, err := ora.OpenEnv(nil) defer env.Close() if err != nil { panic(err) } 

We see that in defer resource closure goes directly through the env link.

But what will happen if a failure occurs. In the OpenEnv implementation , we see that the error for env returns the value nil. With emit this situation:

 package main import ( "gopkg.in/rana/ora.v3" "errors" ) func main() { defer fmt.Println("Hello") // env, err := ora.OpenEnv(nil) var env *ora.Env = nil var err error = errors.New("Test error") defer env.Close() if err != nil { panic(err) } } 

We get the following error message:

Hello
panic: Test error
panic: runtime error: invalid memory address or nil pointer dereference [signal 0xc0000005 code = 0x1 addr = 0x0 pc = 0x48753a]

goroutine 1 [running]:
gopkg.in/rana/ora%2ev3.(*Env).Close(0x0, 0x0, 0x0)

And even though we see that the resulting error does not interrupt the execution of the remaining defer methods, but the error is still fixed.

Is it correct to leave it like this?
Or is it still worth ensuring that with evn == nil defer env.Close() will never be called?
Or in the body of the method passed to defer , should env be checked for nil ?

 defer func () { if env != nil { env.Close() }}() 

    1 answer 1

    defer usually set after checking for an error, just because most functions returning a pointer and error return nil in case of an error. For example:

     f, err := os.Open(os.Args[1]) if err != nil { panic(err) } defer f.Close() 

    The example in that library is really strange from this point of view. EMNIP, all examples in the standard library call defer after checking. For example, in database/sql .

    • Don't you think that using log.Fatal(err) is also not correct. After all, the implementation of log.Fatal contains os.Exit(1) , i.e. program execution will be interrupted and "Hello" will not be output, i.e. other resources will not be correctly closed. - mals
    • This is just an example. Replaced by panic . - Ainar-G
    • But, if this pattern is considered as a standard, then what guarantees that f == nil ? And if it is not nil , then for reliability all the same it is worth pulling Close ? Those. I want to say that this template is not universal, there is a condition in it. - mals
    • There is no guarantee. Even if there is a situation in which f != nil , there is no guarantee that f.Close() does not break, panic or return another error. Look at the situation, the specific resources, the documentation module and the requirements for sustainability. - Ainar-G
    • one
      @MaLS, well, in C # no one guarantees to you either that in finally the link to the resource is not null - hardsky