There's a Go issue which is relevant here: https://github.com/golang/go/issues/8082
On Sat, 25 May 2019 at 04:54, Dan Kortschak <d...@kortschak.io> wrote: > The interfaces that define the contracts should come from a third > package/source. The issue that I suspect you are hitting is that type > identity for interface types is based on the name, not the method set. > This means that, for example with your code below a function > PrintB(StringerB) and another function PrintA(StringerA) are not > assignable to the same variable unless it is type interface{}. > > https://play.golang.org/p/a8aWwA6CAB_K // remove comment to see failure > > On Fri, 2019-05-24 at 20:38 -0700, Henry wrote: > > Thanks for the reply. > > > > Is there any specific use case that this intended behavior is > > supposed to > > solve? It appears to me that it is just a case of simplistic > > implementation > > where Go does not look deep enough to see if any dependent interfaces > > are > > identical. In this case, Go does not bother to look beyond Formatter > > interface in order to conclude whether FormatterA and FormatterB are > > identical. In here, I define 'identical' as being interchangeable, > > rather > > than semantic equality. So when I refer to TypeA and TypeB as > > identical, it > > means you can use TypeA in place of TypeB, and vice versa. > > > > Back to the actual situation, Package A and Package B are developed > > in > > tandem by different teams. They have some communication on how their > > components will interact with each other and fit the bigger picture. > > They > > use interface to define contracts that are required in order for > > their > > components to work. Since Go interface is implicit, this is supposed > > to > > work fine. As an example, if I were to reduce the prior example as > > follows, > > it works fine. (Link to the playground: > > https://play.golang.org/p/zrpjSYTIyxZ) > > > > import ( > > "fmt" > > ) > > > > func main() { > > str := MyString("Hello world!") > > Print(str) > > > > strA:=StringerA(str) > > Print(strA) > > } > > > > type StringerA interface { > > String() string > > } > > > > type StringerB interface { > > String() string > > } > > > > type MyString string > > > > func (s MyString) String() string { > > return string(s) > > } > > > > func Print(s StringerB) { > > fmt.Println(s.String()) > > } > > > > However, when I add a more complex interface, as in the first > > example > > involving Formatter, it breaks. Go fails to recognize that FormatterA > > and > > FormatterB are interchangeable despite the facts that their > > dependencies > > (StringerA and StringerB) are interchangeable. Visually, the > > components > > should look like this: > > > > [image: go.png] > > Let me know what you think. > > > > Thanks. > > > > Henry > > > > On Saturday, May 25, 2019 at 1:54:11 AM UTC+7, Wagner Riffel wrote: > > > > > > It's not a bug, FormatterA and FormatterB method has different > > > signatures, they are not identical, one wants Format(StringerA) > > > other > > > Format(StringerB), thus your Format type only implements > > > FormatterA > > > but Print wants a FormatterB. > > > > > > > > > -- > 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/71965bccd27ed0288b09f9b5b1b3dfc75b3a4ef2.camel%40kortschak.io > . > For more options, visit https://groups.google.com/d/optout. > -- 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/CAJhgachMAM1X9yKF5tNoSaNxOnEmWPnGr4Akiq6jp_j%3DZoO4HA%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.