go的fmt包打印和字符串的格式化
约 1501 字大约 5 分钟
作者:程序员CKeen 
博客:http://ckeen.cn
长期坚持做有价值的事!积累沉淀,持续成长,升维思考!希望把编码作为长期兴趣爱好😄
fmt包提供了类似于C的print和scan的函数实现格式化I/O。 fmt主要提供了输出和输入两大类型的函数以及字符串格式化的的方法。
1.标准库fmt提供几种输出/输入相关函数。
1.1 Print系列函数会将内容输出到系统的标准输出
- Print系列函数会将内容输出到系统的标准输出
- Printf函数支持格式化输出字符串到系统的标准输出
- Println函数会在输出内容的结尾添加一个换行符,输出到系统的标准输出
- Fprint系列函数会将内容输出到一个io.Writer接口类型的变量w中,我们通常用这个函数往文件中写入内容。
- Sprint系列函数会把传入的数据生成并返回一个字符串。
- Errorf函数根据format参数生成格式化字符串并返回一个包含该字符串的错误。
相对于fmt输出,fmt 提供了相对应的输入函数:
- 从标准输入获取用户的输入。
- 根据format参数指定的格式,从标准输入读取数据
- 从标准输入获取数据,直到获取到换行符结束
- 和Fprint相对应的Fscan,从io.Reader中读取数据
- 和Sprint相应的Sscan, 从字符串中读取
标准提供了从标准输入、文件以多种形式进行读取,以及输出到标准输入、文件等。其中某些函数还提供按占位符的形式输出格式化数据。
2. 格式化数据占位符
*printf系列函数都支持format格式化参数,占位符将被替换的变量实际值,这里我们按格式化数据类型划分
这里我们先定义一个Person的结构,作为后续的示例:
type Person struct {
	Name string
	Age  int
}
person := &Person{
    Name: "Xiao Ming",
	Age:  18,
}
- 通用格式化 - 占位符 - 说明 - 示例说明 - %v - go的默认打印格式 - 打印person结构:&{Xiao Ming 18} - %+v - 当打印结构体时,添加字段名 - 打印person结构:&{Name:Xiao Ming Age:18} - %#v - 值的go语法表示 - 打印person结构: &main.Person{Name:"Xiao Ming", Age:18} - %T - go中值的类型 - 字符串切片格式化:[]string - %% - 打印原始的%符号 
- bool类型 - 占位符 - 说明 - 示例说明 - %t - 格式化bool类型变量 - true/false 
- 整型 - 占位符 - 说明 - 示例说明 - %b - int格式为二进制数据 - 例如65对应的值为:1000001 - %c - int类型对应的Unicode码位所表示的字符 - 例如65对应的为字母A - %d - 格式化为十进制整数 - %o - 格式化为八进制整数 - 例如65格式化输出:101 - %O - 格式化为带0o前缀的八进制整数 - 例如65格式化输出:0o101 - %q - 该值对应的单引号括起来的go语法字符字面值, 必要时会采用安全的转义表示 - %x - 表示为十六进制,使用a-f - 例如255输出为ff - %X - 表示为十六进制,使用A-F - 例如255输出为FF - %U - 表示为Unicode格式:U+1234,等价于"U+%04X" 
- 浮点数和复数 - 占位符 - 说明 - 示例说明 - %b - 格式化bool类型 - %e - 科学计数法,e表示 - 123.321的格式化输出: 1.233210e+02 - %E - 科学计数法,E表示 - 123.321的格式化输出: 1.233210E+02 - %f - 有小数格式,无指数表示形式 - 123.321的格式化输出:123.321 - %F - 同%f - %g - 根据实际情况采用%e或%f输出, 如果数比较大%e输出 - %G - 根据实际情况采用%E或%f输出, 如果数比较大%E输出 - %x - 每个字节用两字节十六进制表示,a-f表示 - 123.321格式化输出:0x1.ed48b43958106p+06 - %X - 每个字节用两字节十六进制表示,A-F表示 - 123.321格式化输出:0X1.ED48B43958106P+06 
- 字符串和字节的切片 - 占位符 - 说明 - 示例说明 - %s - 直接输出字符串或者[]byte - “A1b加2c3”格式化输出:A1b加2c3 - %q - 双引号括起来的字符串 - “A1b加2c3”格式化输出:"A1b加2c3" - %x - 每个字节用两字节十六进制表示,a-f表示 - “A1b加2c3”格式化输出:413162e58aa0326333 - %X - 每个字节用两字节十六进制表示,A-F表示 - “A1b加2c3”格式化输出:413162E58AA0326333 
- 指针 - 占位符 - 说明 - 示例说明 - %p - 0x开头的十六进制数表示 - person格式化输出:0xc0000a7248 
- 宽度标识符 宽度通过一个紧跟在%后面的十进制数指定,如果未指定宽度,则表示值时除必需之外不作填充。精度通过点号后面的十进制数指定,没指定表示精度为0。举例如下 - 占位符 - 说明 - 示例说明 - %f - 默认宽度,默认精度 - %9f - 宽度9,默认精度 - 123.321格式化输出:123.321000 - %.2f - 默认宽度,精度2 - 123.321格式化输出:123.32 - %9.2f - 宽度9,精度2 - 123.321格式化输出: 123.32, 前面补4个空 - %9.f - 宽度9,精度0 - 123.321格式化输出: 123, 前面补6个空 
3.使用fmt个格式化遇到的问题
- String()方法格式化无限递归的问题 - type X string func (x X) String() string { return fmt.Sprintf("<%s>", x) } func main (){ var x X x = "hello" fmt.Print(x.String()) }
- 如果给占位符提供了无效的实参,所生成的字符串会包含该问题的描述,而不是你想要的结果。 - foo := "bar" fmt.Printf("%d", foo) // 输出打印结果:%!d(string=bar)
