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.

Reply via email to