promoted methods confusion

113 views
Skip to first unread message

mi...@ubo.ro

unread,
Feb 22, 2021, 3:52:17 PM2/22/21
to golang-nuts
Is there any proposal in Go 2.0 to remove the promotion of methods on embedded struct fields or do you think it's a good idea ? For example in the code below if someone marshals `Pack`, only `Animal` is actually marshalled. Cat field is skipped. If he wants to marshal Cat as well the developer must write an additional wrapper method(MarshalJSON) on `Pack` and any other struct that embeds `Animal`. This becomes an even bigger issue if you create types dynamically (using reflect). Actually I believe reflect.StructOf is actually broken because of this feature (i.e. it panics if the embedded type has methods).


 type Pack struct{
     Animal
     Cat Cat
 }

 func (a *Animal)MarshalJSON()([]byte, error){
     // custom animal marshalling
 }

Ian Lance Taylor

unread,
Feb 22, 2021, 11:32:51 PM2/22/21
to mi...@ubo.ro, golang-nuts
There are no plans to remove method promotion. It's true that method
promotion can lead to surprising results. Programs should only use
embedded fields when they can take full responsibility for all the
consequences.

Ian

Henry

unread,
Feb 23, 2021, 1:01:27 AM2/23/21
to golang-nuts
I think the problem is that people try to use embedding in place of inheritance. You can see that in the original author's example involving Cat, Animal, and Pack. Embedding shares many similarities to inheritance, such as method promotion, but they are not the same. Embedding is in a way more restricted and less capable than inheritance in other languages, because embedding is just a plain syntax sugar. In the original author's example, calling pack.MarshalJSON() is actually calling pack.Animal.MarshalJSON(). When used in the context of inheritance, it becomes misleading because pack.MarshalJSON() implies marshalling the Pack when it is actually marshalling the Animal in the Pack.

Volker Dobler

unread,
Feb 23, 2021, 3:58:38 AM2/23/21
to golang-nuts

On Tuesday, 23 February 2021 at 07:01:27 UTC+1 Henry wrote:
I think the problem is that people try to use embedding in place of inheritance. [...] Embedding shares many similarities to inheritance

The first part is a real common problem but I have to admit I do not understand
where the second part originates from: Embedding has _nothing_ in common
with inheritance. The syntactic sugar of method promotion has a priori nothing
to do with embedding and embedding basically lacks any property defining what
inheritance is.

To me it is really astonishing how often e.g. on Stackoverflow people come up
with elaborate Animal-Speak-Dog-Bark-Cat-Miaow variations based on embedding
which just don't work, well of course because embedding is not and cannot
be used to mimic inheritance. Even with the syntactic sugar of method promotion.

Maybe the FAQ or other introductory material should contain a paragraph like:
  "Can I model inheritance with embedding?
   No, sorry, this is not possible."
And
   "But if I try very hard and do clever stuff?"
   No, it still is not inheritance. It simply cannot be done, no matter
   how hard you try and how clever your code mights seem.

V.

Reply all
Reply to author
Forward
0 new messages