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))
}