Consider the code below. serial.Open returns an interface. When the lower-level open functions return an error, the nil pointer of the platform specific port type that goes along with it is nil, and when this is returned as the serial.Open interface, comparing this with nil is somewhat confusing. One could argue that user of serial.Open should understand this and set their d.conn below to nil themselves. But the semantics of interfaces is a bit confusing in this case.
If the lower-level open returns nil, I suggest that serial.Open explicitly returns nil, err (nil being a nil of the type nil). I think this won't have any bad consequences, because the lower-level port structs are not exported, so there is nobody trying to cast to them.
package main
import (
"fmt"
"go.bug.st/serial"
)
type device struct {
conn serial.Port
}
func main() {
var d device
var err error
d.conn, err = serial.Open("/dev/pts/242", &serial.Mode{})
if err != nil {
fmt.Println(err)
}
if d.conn != nil {
d.conn.Close()
} else {
fmt.Println("interface is NOT nil, so never close conn!")
}
}
Consider the code below. serial.Open returns an interface. When the lower-level open functions return an error, the nil pointer of the platform specific port type that goes along with it is nil, and when this is returned as the serial.Open interface, comparing this with nil is somewhat confusing. One could argue that user of serial.Open should understand this and set their
d.conn
below to nil themselves. But the semantics of interfaces is a bit confusing in this case.If the lower-level open returns nil, I suggest that serial.Open explicitly returns
nil, err
(nil being a nil of the type nil). I think this won't have any bad consequences, because the lower-level port structs are not exported, so there is nobody trying to cast to them.