I don’t think that represents the problem fairly. In the non interface case I know I can’t accept a copy so I would declare the method as taking a pointer to the struct.
With interfaces this is lost - as the interface is implicitly a pointer - but whether it points to a copy or the original is unknown because the dev writing the interface declaration and function using the interface only knows they need something with a Log(). It is the implicit copying for the interface which makes it obtuse. > On Jun 7, 2021, at 12:57 PM, Axel Wagner <axel.wagner...@googlemail.com> > wrote: > > >> On Mon, Jun 7, 2021 at 7:42 PM Robert Engels <reng...@ix.netcom.com> wrote: > >> I think that is my point. The methods in the code I shared have a proper >> receiver type based on the requirements of the methods. > > No, they don't. The `Log` method requires a pointer receiver, as it accesses > state that is supposed to be shared. Once you fix that, the compiler will > quite correct complain that the value does not implement the interface in > question. > > Note that the code behaves the same even if no interfaces are involved: > https://play.golang.org/p/WpIzYYLOKn- > >> So it seems to me that go lint should at least complain that a struct has >> mutating methods so all methods should take pointer receivers. > > I disagree. > >> >> >>>> On Jun 7, 2021, at 9:19 AM, 'Axel Wagner' via golang-nuts >>>> <golang-nuts@googlegroups.com> wrote: >>>> >>> >>> FWIW I do tend to mix value and pointer receivers occasionally. >>> Sometimes a type needs a pointer receiver in one method, but a different >>> method doesn't and it's more convenient to have a copy available for >>> temporary operations. >>> Usually when I implement flag.Var, I make `Set` use a pointer receiver and >>> `String` use a value receiver - because why not? There is no pointer needed >>> to stringify a value. >>> Sometimes I have a slice type which should generally be used and passed as >>> a value, but for convenience, I add a `push`/`pop` method to it, with a >>> pointer receiver. >>> >>> Of course, all of these things *could* be accomplished by just using >>> pointer-receivers everywhere. But by that same logic, why have value >>> receivers anyway? You *could* always use a pointer. >>> >>> I don't think it's a huge problem to mix the two. It's true that this means >>> the pointer and the value type implement different interfaces - but I don't >>> think that's a huge problem either. I *definitely* doubt that it's "the >>> most inconsistent and obtuse aspect of the Go language". I'm not saying it >>> *never* caused any problems for me, but it definitely isn't as frequent a >>> source of bugs as the behavior of closures in loops, or slices >>> unintentionally sharing elements after append… All of which I'm fine with >>> as well. >>> >>> But FTR, this discussion is definitely off-topic in this thread. And it's >>> also moot in general: It's not something we can realistically change now. >>> >>>> On Mon, Jun 7, 2021 at 3:05 PM Robert Engels <reng...@ix.netcom.com> wrote: >>>> >>>> There is no good reason that proper behavior should be dependent on >>>> understanding best practices. It should help with readability not >>>> correctness. Seems to me the compiler or Go Vet should prohibit this - in >>>> my review of the stdlib and other projects I can’t see any reason why it >>>> doesn’t. >>>> >>>>>> On Jun 6, 2021, at 11:10 AM, jake...@gmail.com <jake6...@gmail.com> >>>>>> wrote: >>>>>> >>>>> >>>>>> On Sunday, June 6, 2021 at 9:33:31 AM UTC-4 ren...@ix.netcom.com wrote: >>>>>> For example, the fact that this code is broken is not intuitively >>>>>> obvious for any reader. It requires way too much scrutiny IMO. >>>>>> >>>>>> https://play.golang.org/p/-f73t_Pm7ur >>>>> >>>>> I would like to note that your example goes against the general advice >>>>> that all methods should be on either pointers or values. Mixing value and >>>>> pointer methods for the same types is a code smell. The code you posted >>>>> is a good example of one of the reasons why. >>>>> >>>>> The second to last paragraph in the FAQ section >>>>> https://golang.org/doc/faq#methods_on_values_or_pointers says: >>>>> "If some of the methods of the type must have pointer receivers, the rest >>>>> should too, so the method set is consistent regardless of how the type is >>>>> used." >>>>> >>>>> In your example, if MyEventRecorder.Log() is changed to have a pointer >>>>> receiver, then the code works as expected: >>>>> https://play.golang.org/p/MG10opC6Ect >>>>> >>>>> -- >>>>> 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/a9b4a8b3-0b2f-4935-807e-1cbca03a3b20n%40googlegroups.com. >>>> >>>> -- >>>> 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/7C376006-EFA0-44BA-A036-B768078E4AA4%40ix.netcom.com. >>> >>> -- >>> 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/CAEkBMfGYRdadYFidvhCKnNqKDeqBSJLWBEU%3DuCJrxr1SbhPepQ%40mail.gmail.com. -- 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/242A4EA1-31B0-41A0-9F4A-7BB27BEC7FEE%40ix.netcom.com.