命令记不住

登陆

标准库 fmt

标准库fmt包

1.格式化I/O

fmt包中有关格式化输入输出的方法有两大: Scan和Print,分别在scan.go和print.go文件中

print.go文件中定义了如下函数:
func Printf(format string,a ..interface{}(n int,err error)
func Fprintf(w io.Writer, format string, a ...interface{})(n int,err error)
         func Sprintf(format string, a...interface{})string

func Print(a ...interface{})(n int, err error)
func Fprint(w io.Writer, a ...interface{})(n int,err error)
func Sprint(a ...interface{})string

func Println(a ...interface{})(n int, err error)
func Fprintln(w io.Writer, a ...interface{})(n int,err error)
func Sprintln(a ...interface{})string

这9个函数,如果按照两个维度来说明,基本上可以说明白了。以上当然这两个维度是为了记忆而定的,并不是官方的说法

(1)如果把Print理解为核心关键字,后缀有f和ln,着重是内容输出的结果样式

如果后缀是f,则指定format

如果后缀是ln,则有换行符

  • Println、Fprintln、Sprintln 输出内容时会加上换行符
  • Print、Fprint、Sprint 输出内容时不加上换行符
  • Printf、Fprintf、Sprintf 按照指定格式化文本输出内容

(2)如果把Print理解为核心关键字,前缀有F和S,着重的是内容输出到的对象。

如果前缀是F,则指定了io.Writer

如果前缀是S,则是输出到字符串

  • Print、Printf、Println 输出内容到标准输出os.Stdout
  • Fprint、Fprintf、Fprintln 输出内容到指定的io.Writer
  • Sprint、Sprintf、Sprintln 输出内容到字符串

sacn.go文件中定义了如下函数:

func Scanf(format string, a ...interface{}) (n int, err error)
func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error)
func Sscanf(str string, format string, a ...interface{}) (n int,err error)

func Scan(a ...interface{}) (n int,err error)
func Fsacen(r io.Reader, a ...interface{}) (n int, err error)
func Sscan(str string, a ...interface{}) (n int,err error)

func Sscanln(a ...interface{})(n int,err error)
func Fscanln(r io.Reader, a ...interface{})(n int,err error)
func Sscanln(str string, a ...interfacce{})(n int,err error)

这9个函数可以扫描格式化文本以生成值,同样也可以按照两个维度来说明

(1)如果把Scan理解为核心关键字,后缀有f和ln,着重的是输入内容的结果样式。

如果后缀是f,则指定了format

如果后缀是ln,则有换行符

  • Scanln、Fscanln、Sscanln 读取到换行符时停止,并要求一次提供一行所有条目
  • Scan、Fscan、Sscan 读取内容时不关注换行
  • Sscanf、Fscanf、Sscanf 根据格式化文本读取

(2)如果把Scan理解为核心关键字,前缀有F和S,着重的是内容输入的来源

如果前缀是F,则指定了io.Reader

如果前缀是S,则是从字符串读取

  • Scan、Scanf、Scanln 从标准输入os.Stdin读取文本
  • Fscan、Fscanf、Fscanln 从指定的io.Reader接口读取文本
  • Sscan、Sscanf、Sscanln 从一个参数字符串读取文本

2.格式化输出

格式化输出是非常有用的一项功能,fmt包中格式化主要的结构体和方法都在format.go文件中定义,格式化输出中字符串由普通字符和占位符组成,例如:

fmt.Printf("value is %+ #8.3[3]v  kg", valF)

上面代码中,%+ #8.3[3]v 是占位符,占位符以%开头,以动词(verb)结尾,格式字符串格式如下“

%[标识][宽度][.精度]动词

Go语言中不同的数据类型所适配的动词不一样,下面根据数据类型分别来讲

(1)通用类动词适用于所有的类型数据

%v      值的默认格式表示,当输出结构体时,扩展标识(%+v)会添加字段名
%#v     值的Go语法表示
%T      值的类型GO语法表示
%%      百分号

(2)布尔类型动词只适用于布尔类型数据

%t      单词true或者false

(3)整形类型动词只适用于整型类型数据

%b      表示为二进制
%c      该值对应的Unicode码值
%d      表示为十进制
%o      表示为八进制
%q      该值对应的单引号括起来的go语法字符字面值,必要时会进行转义表示
%x      表示为十六进制,适用a-f
%X      表示为十六进制,使用A-F
%U      表示为Unicode格式U+1234等价于“U+%04X”

(4)浮点和复数类型动词适用于浮点类型和复数类型数据

%b      无小数部分、二进制指数的科学计算法,如-123456平-78;参见strconv.FormatFloat
%e      科学计数法,如-1234.456e+78
%E      科学计数法,如-1234.456E+78
%f      有小数部分,但无指数部分,如123.456
%F      等价于%f
%g      根据实际情况采用%e或%f格式(以获得更简洁,准确的输出)
%G      根据实际情况采用%E或%F格式(以获得更简洁、准确的输出)

(5)字符串和字符数组动词适用于字符串和字节数组类型数据

%s      直接输出字符串或[]byte
%q      该值对应双引号括起来的Go语法字符串字面值,必要时会用转义表示
%x      每个字节用两字符十六进制数表示(使用a-f)
%X      每个字节用两字符十六进制数表示(使用A-F)

(6)指针类型动词适用于指针类型数据

%p      表示为十六进制,并加上前导的0x

(7)宽度通过一个紧跟在百分号后面的十进制数指定,如果未指定宽度,则表示值时除必需之外不作填充。精度通过在宽度后加点号和十进制数来指定。如果未指定精度,会使用默认精度,如果点号后没有跟数字,表示精度为0

对于整数,宽度和精度都设置输出总长度。采用精度时表示右对齐并用0填充,而宽度默认表示用空格填充。

对于浮点数,宽度设置输出总长度,精度设置小数部分长度,除了%g/%G,此时精度设置总的数字个数,例如123.45,格式%6.2f输出123.45,格式%.4g输出123.5。%e和%f的默认精度是6,%g的默认精度是可以将该值区分出来需要的最小数字个数。

对复数,宽度和精度会分别用于实部和虚部,结果用小括号包裹。因此%f用于诸如1.2+3.4i的输出(1.200000+3.400000i)

%f      默认宽度,默认精度
%9f     宽度9,默认精度
%.2f    默认宽度,精度2
%9.2f   宽度9,精度2
%9.f    宽度9,精度0

(8)在格式字符串中标识flag是可选的

+       总是输出数值的正负号,对%q(%+q)会生成全部是ASCII字符的输出(通过转义)
-       在输出右边而不是默认的左边填充空白(既从默认的右对齐切换为左对齐)
#       切换格式

‘’      对数值,正数前面加空格而负数前加负号
        对字符串采用%x或%X时会给各打印的字节之间加空格
0       使用0而不是空格填充,对于数值类型会把填充的0放在正负号后面

在格式字符串中动词会忽略不支持的标识

package main

import (
    "fmt"
    "os"
)

type User struct {
    name string
    age  int
}

var valF float64 = 32.9983
var valI int = 89
var valS string = "Go is an open source programming language that makes it easy to build simple,  reliable,  and efficient software."
var valB bool = true

func main() {

    p := User{"John", 28}

    fmt.Printf("Printf struct %%v : %v\n", p)
    fmt.Printf("Printf struct %%+v : %+v\n", p)
    fmt.Printf("Printf struct %%#v : %#v\n", p)
    fmt.Printf("Printf struct %%T : %T\n", p)

    fmt.Printf("Printf struct %%p : %p\n", &p)

    fmt.Printf("Printf float64 %%v : %v\n", valF)
    fmt.Printf("Printf float64 %%+v : %+v\n", valF)
    fmt.Printf("Printf float64 %%#v : %#v\n", valF)
    fmt.Printf("Printf float64 %%T : %T\n", valF)
    fmt.Printf("Printf float64 %%f : %f\n", valF)
    fmt.Printf("Printf float64 %%4.3f : %4.3f\n", valF)
    fmt.Printf("Printf float64 %%8.3f : %8.3f\n", valF)
    fmt.Printf("Printf float64 %%-8.3f : %-8.3f\n", valF)
    fmt.Printf("Printf float64 %%e : %e\n", valF)
    fmt.Printf("Printf float64 %%E : %E\n", valF)

    fmt.Printf("Printf int %%v : %v\n", valI)
    fmt.Printf("Printf int %%+v : %+v\n", valI)
    fmt.Printf("Printf int %%#v : %#v\n", valI)
    fmt.Printf("Printf int %%T : %T\n", valI)
    fmt.Printf("Printf int %%d : %d\n", valI)
    fmt.Printf("Printf int %%8d : %8d\n", valI)
    fmt.Printf("Printf int %%-8d : %-8d\n", valI)
    fmt.Printf("Printf int %%b : %b\n", valI)
    fmt.Printf("Printf int %%c : %c\n", valI)
    fmt.Printf("Printf int %%o : %o\n", valI)
    fmt.Printf("Printf int %%U : %U\n", valI)
    fmt.Printf("Printf int %%q : %q\n", valI)
    fmt.Printf("Printf int %%x : %x\n", valI)

    fmt.Printf("Printf string %%v : %v\n", valS)
    fmt.Printf("Printf string %%+v : %+v\n", valS)
    fmt.Printf("Printf string %%#v : %#v\n", valS)
    fmt.Printf("Printf string %%T : %T\n", valS)
    fmt.Printf("Printf string %%x : %x\n", valS)
    fmt.Printf("Printf string %%X : %X\n", valS)
    fmt.Printf("Printf string %%s : %s\n", valS)
    fmt.Printf("Printf string %%200s : %200s\n", valS)
    fmt.Printf("Printf string %%-200s : %-200s\n", valS)
    fmt.Printf("Printf string %%q : %q\n", valS)

    fmt.Printf("Printf bool %%v : %v\n", valB)
    fmt.Printf("Printf bool %%+v : %+v\n", valB)
    fmt.Printf("Printf bool %%#v : %#v\n", valB)
    fmt.Printf("Printf bool %%T : %T\n", valB)
    fmt.Printf("Printf bool %%t : %t\n", valB)

    fmt.Printf("Printf %%f : %f\n", 1.2+3.4i)
    s := fmt.Sprintf("a %s", "string")
    fmt.Println(s)

    fmt.Fprintf(os.Stderr, "an %s\n", "error")

}

程序输出:

Printf struct %v : {John 28}
Printf struct %+v : {name:John age:28}
Printf struct %#v : main.User{name:"John", age:28}
Printf struct %T : main.User
Printf struct %p : 0xc0000ae018
Printf float64 %v : 32.9983
Printf float64 %+v : 32.9983
Printf float64 %#v : 32.9983
Printf float64 %T : float64
Printf float64 %f : 32.998300
Printf float64 %4.3f : 32.998
Printf float64 %8.3f :   32.998
Printf float64 %-8.3f : 32.998  
Printf float64 %e : 3.299830e+01
Printf float64 %E : 3.299830E+01
Printf int %v : 89
Printf int %+v : 89
Printf int %#v : 89
Printf int %T : int
Printf int %d : 89
Printf int %8d :       89
Printf int %-8d : 89      
Printf int %b : 1011001
Printf int %c : Y
Printf int %o : 131
Printf int %U : U+0059
Printf int %q : 'Y'
Printf int %x : 59
Printf string %v : Go is an open source programming language that makes it easy to build simple,  reliable,  and efficient software.
Printf string %+v : Go is an open source programming language that makes it easy to build simple,  reliable,  and efficient software.
Printf string %#v : "Go is an open source programming language that makes it easy to build simple,  reliable,  and efficient software."
Printf string %T : string
Printf string %x : 476f20697320616e206f70656e20736f757263652070726f6772616d6d696e67206c616e67756167652074686174206d616b6573206974206561737920746f206275696c642073696d706c652c202072656c6961626c652c2020616e6420656666696369656e7420736f6674776172652e
Printf string %X : 476F20697320616E206F70656E20736F757263652070726F6772616D6D696E67206C616E67756167652074686174206D616B6573206974206561737920746F206275696C642073696D706C652C202072656C6961626C652C2020616E6420656666696369656E7420736F6674776172652E
Printf string %s : Go is an open source programming language that makes it easy to build simple,  reliable,  and efficient software.
Printf string %200s :                                                                                        Go is an open source programming language that makes it easy to build simple,  reliable,  and efficient software.
Printf string %-200s : Go is an open source programming language that makes it easy to build simple,  reliable,  and efficient software.                                                                                       
Printf string %q : "Go is an open source programming language that makes it easy to build simple,  reliable,  and efficient software."
Printf bool %v : true
Printf bool %+v : true
Printf bool %#v : true
Printf bool %T : bool
Printf bool %t : true
Printf %f : (1.200000+3.400000i)
a string
an error

主要通过fmt.Printf来理解这些verb的含义,这对今后的开发有比较强的实际作用

3.fmt

fmt 技巧:

多个 % 要求提供相同数目的操作数,而 % 后的副词[1]告知 Printf 重复使用第一个操作数,其次 %o,%x 或 %x 之前的副词 # 告知 Printf 输出相应的前缀 0,0x 或 0x.

func main() {
	ascii := 'a'
	x := 0xdeadbeef

	fmt.Printf("%d %[1]c %[1]q\n", ascii)
	fmt.Printf("%d %#x  %#X\n", x, x, x)
}

//97 a 'a'
//3735928559 0xdeadbeef  0XDEADBEEF

4.fmt.Fprintf

使用fmt.Fprintf格式化,然后将相应发送出去,Web服务器使用fmt.Fprintf通过写入http.ResponseWriter来让浏览器显示

func main() {
	http.HandleFunc("/", handler)
	log.Fatal(http.ListenAndServe("127.0.0.1:8000", nil))
}

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "URL.Path = %q\n", r.URL.Path)
}