preface

The FMT package implements formatted I/O similar to the C languages printf and scanf. The formatting action (‘verb’) comes from C but is simpler. This article introduces the functions of Stringer, GoStringer, State, and Formatter interfaces.

Stringer interface

type Stringer interface {
	String() string
}
Copy the code

If an object implements the Stringer interface,% s,%v prints to determine whether the object implements the Stringer interface. If it does, the object’s String method is called.

package main

import "fmt"

type person struct {
	Name string
	age int
}

func (p *person) String(a) string {
	return p.Name
}

func main(a) {
	p := &person{"jack".22}

	println(p)           // 0xC000090000, this prints the address
	fmt.Println(p)       // jack
	fmt.Printf("%v\n",p) // jack
	fmt.Printf("%s\n",p) // jack
}

Copy the code

For the built-in println() function, print() cannot call the String method.

For some structures, the Stringer interface can be implemented to hide certain fields when they are not intended to be printed.

GoStringer interface

type GoStringer interface {
	GoString() string
}
Copy the code

An object that implements the GoStringer interface, when formatted in %#v (or any other form?) , the GoString method is called to generate a go syntax representation of the output that defines the value of the type. Person {Name:”jack”, age:22} this style is the GO syntax for representing an object, but we can define it ourselves.

package main

import (
	"encoding/json"
	"fmt"
)

type person struct {
	Name string
	age int
}

func (p *person) GoString(a) string {
	b, _ :=json.Marshal(p)
	return string(b)
}

func main(a) {
	p := &person{"jack".22}

	fmt.Printf("%v\n",p)    // &{jack 22}
	fmt.Printf("%#v\n",p)   // {"Name":"jack"}, GoString output
	fmt.Printf("%+v\n",p)   // &{Name:jack age:22}
}
Copy the code

Here we implement the GoStringer interface and return the object json serialized string to achieve the go syntax representation of the rewrite object.

The State interface

type State interface {
    The Write method is used to Write formatted text
    Write(b []byte) (ret int, err error)
    // Width returns the Width value and whether it is set
    Width() (wid int, ok bool)
    // Precision Returns the Precision value and whether it is set
    Precision() (prec int, ok bool)
    // Flag Indicates whether Flag C (one character, such as +, -, and #) is set.
    Flag(c int) bool
}
Copy the code

Before we look at the State interface, let’s look at the formatting syntax of GO

% indicates the start of formatting

The + sign followed by % indicates flags

3.2 after + denotes Width and Precision

F is the placeholder verb

The GO formatting syntax consists of five parts: start position, flags, width, precision, and placeholders, and the State interface contains three of them. After parsing a %+3.2f structure, the data is saved to State. The next step is to call printArg for formatting and write the formatted data to buffer. After parsing all structures, write to IO. And output it to the console (more on how the code is implemented later).

The Formatter interface

type Formatter interface {
	Format(f State, c rune)}Copy the code

The Formatter is used to implement custom formatting methods. You can do this by implementing the Format method in a custom structure. Used in the standard library in/usr/local/go/SRC/FMT/print. Go: 580, will first determine whether structure realizes the Formatter interface, realized with custom Formatter format parameters. If not, the default rules of go syntax format GoStringer are used to format parameters to the maximum extent, followed by error and Stringer interface.

Let’s see how dachang STATION B implements this interface

// Format is a support routine for fmt.Formatter. It accepts the decimal
// formats 'd' and 'f', and handles both equivalently.
// Width, precision, flags and bases 2, 8, 16 are not supported.
func (x *Dec) Format(s fmt.State, ch rune) {
	ifch ! ='d'&& ch ! ='f'&& ch ! ='v'&& ch ! ='s' {
		fmt.Fprintf(s, "% %! %c(dec.Dec=%s)", ch, x.String())
		return
	}
	fmt.Fprintf(s, x.String())
}

Copy the code

Isn’t that easy? 😝

summary

This section introduces several basic interfaces and uses in the FMT package. In the next article, we’ll dive into the implementation of the FMT package.