深入理解Go语言的fmt包 – 格式化I/O指南
1. fmt包概述
Go语言的fmt包提供了格式化输入输出的功能,是Go标准库中最常用的包之一。它实现了类似C语言的printf和scanf的功能,但更加简单和安全。
2. 主要功能
2.1 格式化输出
fmt包提供了多种输出函数:
Print
系列:标准输出Sprint
系列:字符串格式化Fprint
系列:向io.Writer写入
fmt.Print("直接输出")
fmt.Printf("格式化输出:%s", "Hello")
str := fmt.Sprintf("格式化字符串:%d", 123)
2.2 格式化输入
fmt包也提供了多种输入函数:
Scan
系列:从标准输入读取Sscan
系列:从字符串读取Fscan
系列:从io.Reader读取
var name string
fmt.Scan(&name) // 从标准输入读取
fmt.Sscanf("Age:25", "Age:%d", &age) // 从字符串解析
2.3 错误格式化
Errorf
:格式化错误信息
err := fmt.Errorf("user %q (id %d) not found", "Alice", 123)
3. 格式化动词详解
fmt包使用格式化动词指定如何格式化值:
3.1 通用动词
%v
:默认格式%+v
:打印结构体时会添加字段名%#v
:Go语法表示%T
:类型表示
type Point struct{X, Y int}
p := Point{1, 2}
fmt.Printf("%v\n%+v\n%#v\n%T\n", p, p, p, p)
3.2 布尔值
%t
:true或false
3.3 整数
%b
:二进制%d
:十进制%o
:八进制%x
:十六进制%c
:对应Unicode码点
fmt.Printf("%b %d %o %x %c\n", 65, 65, 65, 65, 65)
3.4 浮点数和复数
%f
:无指数%e
/%E
:科学记数法%g
/%G
:根据情况选择%e或%f
fmt.Printf("%f %e %g\n", 123.456, 123.456, 123.456)
3.5 指针
%p
:指针地址
3.6 宽度和精度
可以在动词前指定宽度和精度:
fmt.Printf("[%5d]\n", 123) // 宽度5
fmt.Printf("[%.2f]\n", 1.2345) // 精度2
fmt.Printf("[%6.2f]\n", 1.2345) // 宽度6,精度2
4. 特殊功能
4.1 Stringer接口
任何实现了String() string方法的类型都可以自定义格式化输出:
type Person struct {
Name string
Age int
}
func (p Person) String() string {
return fmt.Sprintf("%v (%v years)", p.Name, p.Age)
}
p := Person{"Alice", 21}
fmt.Println(p) // 自动调用String()方法
4.2 GoStringer接口
类似Stringer,但在%#v时调用:
func (p Person) GoString() string {
return fmt.Sprintf("Person{Name:%q, Age:%d}", p.Name, p.Age)
}
fmt.Printf("%#v\n", p)
5. 错误处理
使用fmt包时需要注意输入函数的错误处理:
var a, b int
n, err := fmt.Sscanf("123 456", "%d %d", &a, &b)
if err != nil {
// 处理错误
}
6. 性能考虑
虽然fmt包非常方便,但在性能敏感的场景下,直接使用字符串拼接或bytes.Buffer可能更高效。
7. 常见陷阱
- 忘记检查Scan函数的返回值
- 格式化字符串与参数类型不匹配
- 指针参数前忘记加&
文末预告
下一期我们将深入学习Go语言的sync
包,探讨Go中的并发同步原语,包括Mutex、RWMutex、WaitGroup等各种同步工具的使用方法和最佳实践。