Thanks Ian for the thorough explanation - again I apologize for asking noob questions :-).
The issue in this case was this error: panic: value method github.com/shirou/gopsutil/process.Process.String called using nil *Process pointer which seems to be coming from the go runtime itself. Certainly the String method of Process does not have a pointer receiver: func (p Process) String() string { s, _ := json.Marshal(p) return string(s) } So it makes sense for the runtime to panic when we attempt to call it on a nil pointer. I looked at the code for the fmt.Sprintf method as you suggested and it seems to be doing the same thing as what my code is doing - i.e. it catches the panic and then calls reflect to check if it is because its a nil pointer. So i guess what feels hacky is really the way it is supposed to be done in golang. I wrote the following code to try to understand the behavior more https://play.golang.org/p/kKWGCeacAEM package main import ( "fmt" ) func type_function(a *int) { fmt.Println("type_function: ", a == nil) } func interface_function(a interface{}) { fmt.Println("interface_function: ", a == nil) } func main() { type_function(nil) // true interface_function(nil) // true var foo *int = nil fmt.Println("is foo nil: ", foo == nil) interface_function(foo) // false ... ? } It seems to me that if a function accepts a pointer type - it is ok to compare a pointer type against nil. But if a function accepts an interface as an arg it is never safe to compare an interface against nil because from inside the function you have no idea if the caller called with actual nil, or a variable who's value is nil (this difference is very weird because this is not how most languages behave - a variable is usually a full substitute to the literal value it holds). It seems to me that the compiler should at least warn when someone is comparing an interface to nil (or maybe the linter should warn). It does not seem that this could ever be what you actually want and it is always a subtle bug just waiting to bite. Thanks Michael. On Wednesday, 9 May 2018, Ian Lance Taylor <i...@golang.org> wrote: > On Tue, May 8, 2018 at 7:19 AM, Michael Cohen <scude...@gmail.com> wrote: > > > > Well no - the error I get is that I am attempting to call String() > method on > > a null receiver - so the caller just passed me a regular nil object. The > > issue is that I am trying to make a generic polymorphic function which > > should be able to handle whatever is thrown at it - so I guess reflect is > > necessary. > > > > I think I am supposed to detect the null receiver before calling > String() > > on it. I ended up using this little utility: > > > > https://stackoverflow.com/questions/13476349/check-for-nil-a > nd-nil-interface-in-go > > > > func isNil(a interface{}) bool { > > defer func() { recover() }() > > return a == nil || reflect.ValueOf(a).IsNil() > > } > > > > > > But this feels really hacky when I really just want to say if value != > nil { > > ....} . > > I think there may be some confusion here. Go doesn't have a "regular > nil object." Specific types can be `nil`. In particular, pointer > types can be `nil`. > > When a type implements a `String` method it is possible to call that > method with a `nil` pointer. In general it is possible to call any > method with a `nil` pointer. That is not an error. > > Some specific implementations of a `String` method may panic when > called with a `nil` pointer. For better or for worse, the fmt package > has special handling for this. > > What this means is that unless you have some special knowledge of the > type you are working with, you should not check for `nil` before > calling the `String` method. For some types the `String` method will > correctly handle `nil`. If you have types with a `String` method that > does not correctly handle `nil`, then it's worth pondering why and how > you got a `nil` pointer for this type in the first place. But if you > can reasonably have a `nil` pointer, and can reasonably expect that > the `String` method will panic in that case, then what you should do > is call `fmt.Sprint(v)`. That will do the right thing whether v's > `String` method handles `nil` or not. > > Ian > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.