7 ms·
Article incorrectly claims that calling a method on a nil value results in an error. Only attempting to dereference the pointer does. It’s fine to call methods
by rvcdbn 6y ago
Article incorrectly claims that calling a method on a nil value results in an error. Only attempting to dereference the pointer does. It’s fine to call methods on nil and that’s part of the “make the zero value useful” philosophy.
- morelisp 6y ago> It’s fine to call methods on nil It's fine to call methods on a concrete nil. But... > that’s part of the “make the zero value useful” philosophy. ... the zero value of an interface is not a concrete nil! And if the interface does contain a concrete nil, it's no longer nil itself! If the goal was to make zero values useful, Go should have rather have offered Obj C-style messages to truly nil interfaces - nothing happens and all values returned are zero.
- fshbbdssbbgdd 6y ago> If the goal was to make zero values useful, Go should have rather have offered Obj C-style messages to truly nil interfaces - nothing happens and all values returned are zero. IMO this is the worst thing about Obj C. The number of times I’ve discovered code that was silently failing in some Obj C project.....
- morelisp 6y agoNow imagine it silently failed half the time, depending on whether or not the nil had crossed an otherwise innocuous function boundary. That's Go.
- philosopher1234 6y agoI don't understand how you can characterize Go as silently failing half the time? Can you give an example of this "silent arbitrary failure"?
- morelisp 6y agoIt's literally the whole thread man. Boxed nils are nils-but-also-not-nils, and knowing if something gets boxed means knowing whether the exact function parameter signature (in or out) is an interface or concrete, not just whether what you are returning is of the appropriate type. (And Go has no special syntax for interface vs. concrete types in parameters, so you not only need to read the signature but the definition of the type.)
- philosopher1234 6y agoI read the thread, but no one ever explained why this matters or would come up in the real world? Just a lot of bluster
- andreygrehov 6y agoYes. That is correct. Here is an interesting piece of code. This will work without an error. package main import ( "fmt" ) func main() { foo := NewFoo() foo.sayHello() } type Foo struct { } func NewFoo() *Foo { return nil } func (f *Foo) sayHello() { fmt.Println("Hello, World") } In Go, the function to be called by the Expression.Name() syntax is entirely determined by the type of Expression and not by the particular run-time value of that expression, including nil.
- deleted 6y ago[deleted]
- cmckn 6y agoThat fact that calling a function on a type does not inherently dereference the pointer seems...nuts. Do gophers routinely check if the pointer is `nil`? If the function does not utilize the pointer (like your example) and so avoids an error, the function probably doesn't need to be defined on the type in the first place. This seems like a bug-prone rough edge to me, coming from Java.
- kitd 6y agoThat fact that calling a function on a type does not inherently dereference the pointer seems...nuts. Only if you come from a vtable-based OO language. Go isn't one, so while it looks unconventional, it is rational.
- kroltan 6y agoOn one hand, it is rational if you think of Go functions "on a type" as just having an extra argument, but then one might ask, why bother with the special syntax at all? Just go the C way and if you want to take a "self", actually take it as a regular parameter. That is: (sorry if the syntax is wrong, I have never used Go) func (f *Foo) sayHello() { ... } Would become func sayHello(f *Foo) { ... } Heck, if you want to keep the value.sayHello() syntax, you can, which would still allow you to build fluent interfaces or whatnot, with the bonus point of being UFCS!