目录
fmt包提供了类似于C的print和scan的函数实现格式化I/O。 fmt主要提供了输出和输入两大类型的函数以及字符串格式化的的方法。
1. 标准库fmt提供几种输出/输入相关函数。
1. Print系列函数会将内容输出到系统的标准输出
func Print(a ...interface{}) (n int, err error)
2.Printf函数支持格式化输出字符串到系统的标准输出
func Printf(format string, a ...interface{}) (n int, err error)
3. Println函数会在输出内容的结尾添加一个换行符,输出到系统的标准输出
func Println(a ...interface{}) (n int, err error)
4. Fprint系列函数会将内容输出到一个io.Writer接口类型的变量w中,我们通常用这个函数往文件中写入内容。
func Fprint(w io.Writer, a ...interface{}) (n int, err error)
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error)
func Fprintln(w io.Writer, a ...interface{}) (n int, err error)
5. Sprint系列函数会把传入的数据生成并返回一个字符串。
func Sprint(a ...interface{}) string
func Sprintf(format string, a ...interface{}) string
func Sprintln(a ...interface{}) string
6. Errorf函数根据format参数生成格式化字符串并返回一个包含该字符串的错误。
func Errorf(format string, a ...interface{}) error
相对于fmt输出,fmt 提供了相对应的输入函数:
1. 从标准输入获取用户的输入。
func Scan(a ...interface{}) (n int, err error)
2. 根据format参数指定的格式,从标准输入读取数据
func Scanf(format string, a ...interface{}) (n int, err error)
3. 从标准输入获取数据,直到获取到换行符结束
func Scanln(a ...interface{}) (n int, err error)
4. 和Fpritn相对应的Fscan,从io.Reader中读取数据
func Fscan(r io.Reader, a ...interface{}) (n int, err error)
func Fscanln(r io.Reader, a ...interface{}) (n int, err error)
func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error)
5. 和Sprint相应的Sscan, 从字符串中读取
func Sscan(str string, a ...interface{}) (n int, err error)
func Sscanln(str string, a ...interface{}) (n int, err error)
func Sscanf(str string, format string, a ...interface{}) (n int, err error)
标准提供了从标准输入、文件以多种形式进行读取,以及输出到标准输入、文件等。其中某些函数还提供按占位符的形式输出格式化数据。
2. 格式化数据占位符
*printf
系列函数都支持format格式化参数,占位符将被替换的变量实际值,这里我们按格式化数据类型划分
这里我们先定义一个Person的结构,作为后续的示例:
type Person struct {
Name string
Age int
}
person := &Person{
Name: "Xiao Ming",
Age: 18,
}
1. 通用
占位符 | 说明 | 示例说明 |
---|---|---|
%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 |
%% | 打印原始的%符号 |
2. bool类型
占位符 | 说明 | 示例说明 |
---|---|---|
%t | 格式化bool类型变量 | true/false |
3. 整型
占位符 | 说明 | 示例说明 |
---|---|---|
%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" |
4. 浮点数和复数
占位符 | 说明 | 示例说明 |
---|---|---|
%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 |
5.字符串和字节的切片
占位符 | 说明 | 示例说明 |
---|---|---|
%s | 直接输出字符串或者[]byte | “A1b加2c3”格式化输出:A1b加2c3 |
%q | 双引号括起来的字符串 | “A1b加2c3”格式化输出:"A1b加2c3" |
%x | 每个字节用两字节十六进制表示,a-f表示 | “A1b加2c3”格式化输出:413162e58aa0326333 |
%X | 每个字节用两字节十六进制表示,A-F表示 | “A1b加2c3”格式化输出:413162E58AA0326333 |
6.指针
占位符 | 说明 | 示例说明 |
---|---|---|
%p | 0x开头的十六进制数表示 | person格式化输出:0xc0000a7248 |
7. 宽度标识符
宽度通过一个紧跟在%后面的十进制数指定,如果未指定宽度,则表示值时除必需之外不作填充。精度通过点号后面的十进制数指定,没指定表示精度为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个空 |
8. 其他占位符
3. 使用fmt个格式化遇到的问题
1. 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())
}
当调用x.String()方法时,X的String()方法调用fmt.Sprintf时,这时候会调用x的String()方法进行格式化字符串导致无限循环递归了。 这里我们需要对String()方法修改为如下形式:
func (x X) String() string {
return fmt.Sprintf("<%s>", string(x))
}
2. 如果给占位符提供了无效的实参,所生成的字符串会包含该问题的描述,而不是你想要的结果。例如:
foo := "bar"
fmt.Printf("%d", foo)
// 输出打印结果:%!d(string=bar)