Confused with Stringer interface

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:

func StringOf(sr fmt.Stringer) string {
    return sr.String()
}

And then call it like this:

s := StringOf(Pen("test"))

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.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.