Some people in comments jump to the conclusion that Go allows conflicting names in embedded structs. It doesn't not – for the embedded structs of the same depth.

These won't compile:

   type Bad struct {
       Name string
       Name string 
   }

   type A struct{ Name string }
   type B struct{ Name string }

   type C struct {
       A
       B
   }

   bad.Name() // compile error: other declaration of Name
   c.Name() // compile error: ambiguous selector c.Name
The case in article is about field names of the different depth. Spec is very clear about this behavior, and it was intentional.

One of the reasons why handling same field names is different at different nesting levels is to protect against changes in structs coming from external libraries. Or, better phrased, external structs should not dictate what names you're allowed to use in your own structs (so they have priority).

I.e. when you create a struct with another embedded struct (possibly from other package):

   type Foo struct {
      somepackage.Bar
      URL string
   }
you don't want to depend on whether Bar already has URL. Your depth level has higher priority.

Even more, imagine in the future authors of `somepackage` decided to add URL to their struct and it suddendly started to break your code from being compiled.

I agree that behavior in the OP article example is confusing (and so is the code - do you want URL of Foo service or Bar service?). Yet, this behavior is intentional and documented.

As usual, it's a subtle tradeoff here. If this feature would be implemented differently (say, compile time error for all depth levels), we would see an article with rant on how external structure changes breaks compilation.

I don't really use golang all that much and even I was confused about OP's point because of the different depths.

I feel like sometimes people just want to complain.

I think author just used to having consistency in Go. If you learned behaviour of one aspect of the language (i.e. compile-time error for conflicting field names), you would expect to have it in all cases. And that's not what's happened in the given example.

> Even more, imagine in the future authors of `somepackage` decided to add URL to their struct and it suddendly started to break your code from being compiled.

doesn't this just shove the problem down a level?

e.g. if somepackage.Bar suddenly gets a member with same name as one of your URL members?

> e.g. if somepackage.Bar suddenly gets a member with same name as one of your URL members?

I think nothing happens there. Your fields "win" on depth and you'd have to access their field with `thing.Bar.Conflicted` (whereas yours would be `thing.Conflicted`).

It could only be a problem if someone embeds both `somepackage.Bar` and `mypackage.Cheese` into `T` with a shared field `X` but then you can't access `T.X` without a runtime error of "ambiguous selector".