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.