On Fri, Apr 10, 2020 at 7:17 PM <cpui...@gmail.com> wrote:

> I realize I'm reviving an age-old discussion here and apologize for
> bringing up the undead. I happend to run into this when my application
> panicked when some interfaces where initialized with nil mock objects
> instead of being left uninitialized as in production mode.
>

Let's imagine a world in which `foo == nil` also is true if `foo` is an
interface-value containing a nil-pointer. Let's say in this world, someone
sends a message to golang-nuts. They wrote a mock for the same code. And
since it's just a mock, they just returned static value from its methods
and didn't need to care if the pointer was nil or not. They are confused,
because the passed in this mock, but the code just assumed the field was
uninitialized and never called into their mock. What would you tell them?
Why is their confusion less valid?

This would be an example where a nil implementing fooer is never caught:
>
> type fooer interface {
>  foo()
> }
>
> type other struct{}
>
> func (o *other) foo() {} // implement fooer
>
> func main() {
>  var f fooer
>
>  var p *other // nil
>  f = p // it is a fooer so I can assign it
>
>  if f == nil {
>     // will not get here
>  }
> }
>
>
> My confusion comes from the point that the nil interface is apparently not
> "a nil-pointer with the correct method set" while *other is even if nil.
>

In the code you posted, even a nil *other is a perfectly fine
implementation of fooer. You can call `(*other)(nil).foo()` without any
problems.
So, as you illustrated, calling methods on a nil-pointer can be totally
fine. A nil-interface, OTOH, doesn't have any methods to call, as it
doesn't contain a dynamic value. If you write `(*other)(nil).foo()`, it is
completely clear what code gets called - even if that code *might* panic.
If you write `fooer(nil).foo()`, what code should be called in your opinion?

I think it's easy to see that a nil-interface and a nil-pointer stored in
an interface are very different things. Even from first principles, without
deep knowledge of the language. And if they are obviously different, I
don't understand why you'd find it confusing that they are not the same in
this particular manner.

The above is a case where that might happen. In can be worked around but it
> is unexpected unless the programmer is deeply rooted in the language
> definition.
>

I fully agree with that. What I *don't* agree with, is where you attribute
the problem here. You say, the problem is that the nil-check is
ill-behaved. I say that - if anything - the original nil-assignment is
ill-behaved. Having `(fooer)((*other)(nil)) == nil` be true is semantically
wrong, because by checking against `nil`, you are checking if you have a
correct implementation - and you might well have a correct implementation,
even if it's using a nil-pointer.

Note, that the contained pointer being nil isn't the *only* case in which
calling the method might panic. For example, what about this code?
https://play.golang.org/p/lNq0qphez7v
Shouldn't the `nil`-check also catch that? After all, calling the method
panics, so it's clearly not a valid implementation - even if x itself is
not nil. Why is a nil-pointer more special than any other value that causes
a method to panic?

Seems as of today that there is no tooling to support that check. Maybe
> it's not a widespread issue.
>

As of today, the language also isn't changed :) Maybe someone who think
this is important enough to change the language, could also feel it's
important enough to write this tooling.


> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/e0dbcd38-510e-43b9-b363-2af1c636250b%40googlegroups.com
> <https://groups.google.com/d/msgid/golang-nuts/e0dbcd38-510e-43b9-b363-2af1c636250b%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAEkBMfEPjcsZ3enqXyt%2BUphFJ1cNQ81cFCcjfwwkQZKHMrjSzA%40mail.gmail.com.

Reply via email to