On Fri, May 24, 2019 at 10:55 AM Henry <henry.adisuma...@gmail.com> wrote:
>
> Hi,
>
> I stumbled across this weird behavior and I wonder whether this is a bug. 
> Here is the simplified version of the problem (Playground link 
> https://play.golang.org/p/mch6NQdTpr5):

I believe this is working as intended because a type implements an
interface if it has the same method signatures as that interface, and
Format(StringerA) is different from Format(StringerB). However, I
wonder if there is any real reason why this is so because it appears
that the type comparison can be "isCompatible" instead of
"isIdentical" for the argument and return types, and things would
still work.

>
> package main
>
> import (
> "fmt"
> )
>
> func main() {
> str := MyString("World")
> var formatter Format
> Print(formatter, str) //ERROR: have Format(StringerA) string, want 
> Format(StringerB) string
> }
>
> //StringerA and StringerB are identical. Some may wonder why declare 
> identical interfaces in the same package.
> //In a real world example, they live in different packages. StringerA resides 
> in Package A and StringerB is in Package B.
>
> type StringerA interface {
> String() string
> }
>
> type StringerB interface {
> String() string
> }
>
>
> //MyString is the concrete implementation of Stringer. It applies to both 
> StringerA and StringerB.
>
> type MyString string
>
> func (m MyString) String() string {
> return string(m)
> }
>
>
> //Then, we have the Formatter. FormatterA and FormatterB are supposed to be 
> identical. They both accept a Stringer.
> //FormatterA accepts StringerA, because they are in the same package. 
> FormatterB accepts StringerB. Package A and Package B
> //are probably authored by different people and they define their own 
> Stringer. However, since we are dealing with interfaces,
> //so behaviour-wise, they are supposed to be identical. They format a 
> Stringer.
>
> type FormatterA interface {
> Format(StringerA) string
> }
>
> type FormatterB interface {
> Format(StringerB) string
> }
>
>
> //Format is the concrete implementation of Formatter. In this case, Format is 
> implemented by the author of Package A. Let's call him Author A.
> //Hence, we see StringerA there because StringerA is Author A definition of 
> Stringer. However, it is intended to work on any Stringer.
>
> type Format struct{}
>
> func (f Format) Format(s StringerA) string {
> return fmt.Sprintf("Hello %s!", s)
> }
>
>
> //Print is written by Author B. She uses FormatterB and StringerB. Those 
> interfaces are the 'contracts' she requires for her function to work.
> //Her intention is for Print to work with any Formatter and any Stringer. 
> However, Go apparently treat FormatterA and FormatterB as being different.
> //Is this a bug?
>
> func Print(f FormatterB, s StringerB) {
> fmt.Println(f.Format(s))
> }
>
>
> Thanks
>
>
> Henry
>
> --
> 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/e5eb2946-e865-40cd-b1f7-3d445d423e00%40googlegroups.com.
> 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/CAMV2RqoW5xBT1vKDdNGWLMitXaMkFUypoNGhcVu0EyLVC4Q6_g%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to