kagxin / blog

个人博客:技术、随笔、生活
https://github.com/kagxin/blog/issues
7 stars 0 forks source link

golang fmt中的接口 #66

Open kagxin opened 3 years ago

kagxin commented 3 years ago

fmt 中的接口

接口

fmt.Stringer

type Stringer interface {
    String() string
}

重写类型默认的格式化字符串占位符%s对应的字符串生成方法。

fmt.GoStringer

type GoStringer interface {
    GoString() string
}

重写类型默认的格式化字符串占位符%#v对应的字符串生成方法。

fmt.State

type State interface {
    // Write is the function to call to emit formatted output to be printed.
    Write(b []byte) (n int, err error)
    // Width returns the value of the width option and whether it has been set.
    Width() (wid int, ok bool)
    // Precision returns the value of the precision option and whether it has been set.
    Precision() (prec int, ok bool)

    // Flag reports whether the flag c, a character, has been set.
    Flag(c int) bool
}

fmt.State由printer解析得到。占位符和fmt.State对应关系是,Width()和Precision()对应位宽和精度,Flag()对应符号位 例如: 占位符%+3.2f中,s.Width()返回值3,s.Percision()返回值2,s.Flag('+')返回值为ture,即判断是否是'+'

fmt.Formatter

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

实现自定义格式化方法,第一个参数实现了fmt.State,第二个参数是占位符类型,即对应%+3.2fff实现了io.Writer接口,通过Write方法将自定义的格式化字串写入

示例

通过给Dog实现fmt.Formatter接口,实现用自定义的占位符%K代替%#v

package main

import (
    "fmt"
)
// Dog dog
type Dog struct {
    Name string
}

// String fmt.Stringer %s
func (n Dog) String() string {
    return fmt.Sprintf("%s", n.Name)
}

// GoString fmt.GoStringer %#v
func (n Dog) GoString() string {
    return fmt.Sprintf("Dog(%s)", n.Name)
}

// Format fmt.Formatter
func (n Dog) Format(s fmt.State, c rune) {
    if c == rune('K') {
        fmt.Fprint(s, n.GoString())
        return
    }
    fmt.Fprint(s, n.String())
}

func main() {
    dog := Dog{Name: "heihu"}
    fmt.Printf("%K\n", dog)
    fmt.Printf("%s\n", dog)
}

输出:

Dog(heihu)
heihu

ref: https://zh.wikipedia.org/wiki/%E6%A0%BC%E5%BC%8F%E5%8C%96%E5%AD%97%E7%AC%A6%E4%B8%B2 https://github.com/golang/go/tree/master/src/fmt