I have a doubt about how the Stringer interface implements a type without doing any package import of “fmt” the “error” interface is builtin into the Go but the Stringer is part of the fmt package.
I have 2 files, I have never called the “fmt” package.
main.go
package main
import "log"
func main() {
log.Fatal(Pen("I'm writing."))
}
strings.go
package main
type Pen string
func (p Pen) String() string {
return string(c)
}
In this way, I can able to implements the String() methods.
I doubted how the Stringer interface will come into the source.
Go interfaces are different from languages like C# and Java, where types have to explicitly implement interfaces. For example, in C#, you can use reflection to find out all the interfaces a type implements. Go’s reflect package doesn’t have that because types in Go don’t “know” what interfaces they implement (i.e. your Pen type doesn’t “know” it implements fmt.Stringer). If I have a function like this:
The compiler knows that this call is safe because the compiler knows that the Pen type has a String function and the fmt.Stringer type needs only a String method with the same signature. The compiler inserts a call to some function in the runtime package (something like runtime.convT2I...) that dynamically builds a fmt.String interface method table from a Pen at runtime and then passes that converted value into StringOf.
So Go types don’t know what interfaces they implement and the runtime doesn’t actually create type-specific interface method tables until runtime, right before a concrete type is passed to a function that takes an interface type as its parameter.