Ian Lance Taylor <i...@golang.org> writes:

> On Wed, Oct 25, 2017 at 1:43 AM, Harald Fuchs
> <hari.fu...@gmail.com> wrote:
>>
>> I got bitten by what I'd say is a misfeature in Go:
>>
>>   type T1 struct {
>>     T2
>>     T3
>>   }
>>
>>   type T2 struct {
>>     T4
>>   }
>>
>>   type T3 struct {
>>     foo int
>>   }
>>
>>   type T4 struct {
>>     foo int
>>   }
>>
>>   func main() {
>>     t1 := T1{
>>       T2{
>>         T4{
>>           1,
>>         },
>>       },
>>       T3{
>>         2,
>>       },
>>     }
>>     fmt.Printf("foo=%d\n", t1.foo)
>>   }
>>
>> This prints "foo=2" which surprised me because I was unaware that T1
>> had got another foo via T3 (with less composition depth).
>>
>> If I put T4 directly into T1, Go would detect the ambiguity of t1.foo
>> (because the composition depth is the same).
>
> What is the misfeature, though?  You gave us a clear explanation of
> what you did and what happened; thanks very  much for doing that.  But
> you didn't say what you expected to happen instead.
>
> I'll speculate that perhaps you would prefer a compilation error due
> to an ambiguous field.

Yes, that's what I would have expected (sorry for not mentioning it).

> Not doing that was an explicit decision.
> Consider a struct in package P1 that embeds two structs, one from
> package P2 and one from P3.  Suppose the struct in P3 embeds another
> struct from P4.  Suppose that all four packages are in different
> github repos maintained by different people; recall that one of the
> explicit goals of the Go language is to support programming at scale.
> With this organization, package P1 can refer directly to fields
> defined in P2 and P3.  We want it to be possible for P4 to add a
> field, a field that might happen to duplicate a field in P2--in this
> example, P2 and P4 might not even know about each other at all--and we
> want that to happen without breaking P1.  Hope that makes sense.

For us, it *did* break P1 in the sense that this silently changing its
semantics.  And how about the following?

  type P1 struct {
    P2
    P3
  }

  type P2 struct {
    P4
  }

  type P3 struct {
    P5
  }

  type P4 struct {
    foo int
  }

  type P5 struct {
    // foo int
  }

P2 and P3 don't know each other.  P1 breaks if P5 gets another foo.
It's almost the same (except composition depth), isn't it?

-- 
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.
For more options, visit https://groups.google.com/d/optout.

Reply via email to