Per the comment:
I'm using the upstreamDebugFile value as an io.WriteCloser. I find it does not give equality with nil, even when the file is not set.
An io.WriteCloser
is an instance of an interface. Meanwhile, os.OpenFile
returns *os.File
, which is a pointer to a struct
. This implements the interface, but is not a value of the type of that interface. That's no big deal for some uses, because the fact that it implements the interface means that you can store the *os.File
value in an io.WriteCloser
.
However, as the following program shows, you must then be careful about testing whether an io.WriteCloser
is nil, because it often isn't:
package main
import (
"fmt"
"io"
"os"
)
func main() {
var iface io.WriteCloser
p, err := os.OpenFile("/bad/foo", os.O_CREATE, 0666)
if err != nil {
fmt.Println(err)
}
fmt.Printf("before assignment, iface = %#v, and iface == nil => %t\n", iface, iface == nil)
iface = p
fmt.Printf("after assignment, iface = %#v, and iface == nil => %t\n", iface, iface == nil)
fmt.Printf("meanwhile p == nil => %t\n", p == nil)
}
Go Playground output:
open /bad/foo: No such file or directory
before assignment, iface = <nil>, and iface == nil => true
after assignment, iface = (*os.File)(nil), and iface == nil => false
meanwhile p == nil => true
Once iface
has an assigned type, you can't just test it as a whole. You must start testing its actual value, of its underlying type, as in this program:
package main
import (
"fmt"
"io"
"os"
)
func main() {
var iface io.WriteCloser
p, err := os.OpenFile("/bad/foo", os.O_CREATE, 0666)
if err != nil {
fmt.Println(err)
}
iface = p
fmt.Printf("iface.(*os.File) == nil => %t\n", iface.(*os.File) == nil)
}
Try it on the Go Playground. But note that if iface
has never been assigned a value of type *os.File
, the type assertion will fail!
If what you're going to store is always going to be *os.File
, just declare your variable to be *os.File
up front:
var foo *os.File
if somecond {
var err error
foo, err = os.OpenFile(... arguments ...)
...
}
// later:
if foo != nil {
...
}
Note that you can also do this:
var iface io.WriteCloser
...
if somecond {
p, err := os.OpenFile(...)
...
if p != nil {
iface = p
}
}
and now iface == nil
suffices again. But unless you're really planning to use multiple different underlying io.WriteCloser
implementations, keep it simple and just use *os.File
directly.