Go 标准库深入学习:fmt 包详解

Go 标准库深入学习:fmt 包详解

fmt 包概述

fmt 是 Go 语言中最基础也最常用的标准库之一,它提供了格式化 I/O 功能,主要用于打印输出和格式化字符串。本文将深入探讨 fmt 包的各个方面,包括格式化动词、扫描函数、格式化函数等核心功能。

格式化输出

Print 系列函数

fmt 提供了多种打印函数:

// 标准输出
fmt.Print("Hello, ")  // 不换行
fmt.Println("World!") // 自动换行
fmt.Printf("Number: %d\n", 42) // 格式化输出

// 格式化字符串
s := fmt.Sprintf("Value: %v", 3.14)

// 拼接字符串
builder := &strings.Builder{}
fmt.Fprintf(builder, "Built: %s", "string builder")

格式化动词

fmt 的格式化动词非常丰富:

// 通用格式化
fmt.Printf("%v\n", struct{ A int }{1}) // 默认格式
fmt.Printf("%+v\n", struct{ A int }{1}) // 带字段名
fmt.Printf("%#v\n", struct{ A int }{1}) // Go语法表示

// 布尔值
fmt.Printf("%t\n", true)

// 整数
fmt.Printf("%d\n", 255) // 十进制
fmt.Printf("%b\n", 255) // 二进制
fmt.Printf("%o\n", 255) // 八进制
fmt.Printf("%x\n", 255) // 十六进制

// 浮点数
fmt.Printf("%f\n", 3.1415926535) // 默认精度
fmt.Printf("%.2f\n", 3.1415926535) // 指定精度
fmt.Printf("%e\n", 3.1415926535) // 科学计数法

// 字符串和切片
fmt.Printf("%s\n", "hello") // 字符串
fmt.Printf("%q\n", "hello") // 带引号字符串
fmt.Printf("%x\n", "hello") // 十六进制

// 指针
v := 42
fmt.Printf("%p\n", &v) // 指针地址

宽度和精度

可以在动词前指定宽度和精度:

fmt.Printf("|%6d|%6d|\n", 12, 345) // 右对齐宽度6
fmt.Printf("|%-6s|%-6s|\n", "foo", "b") // 左对齐宽度6
fmt.Printf("|%6.2f|\n", 1.2) // 宽度6精度2
fmt.Printf("|%*.*f|\n", 6, 2, 1.2) // 动态宽度和精度

输入扫描

Scan 系列函数

fmt 也提供了从标准输入读取数据的功能:

var name string
var age int

// 从标准输入读取,空格分隔
fmt.Scan(&name, &age)

// 支持格式化的扫描
fmt.Scanf("%s is %d years old", &name, &age)

// 扫描一行
input := "Hello 25"
fmt.Sscan(input, &name, &age)

// 从字符串格式化扫描
fmt.Sscanf("Name: Alice, Age: 25", "Name: %s, Age: %d", &name, &age)

扫描注意事项

// 处理扫描错误
n, err := fmt.Sscanf("Invalid input", "%d", &age)
if err != nil {
    fmt.Println("Parse error:", err)
    fmt.Println("Successfully parsed items:", n)
}

自定义类型的格式化

可以为自定义类型实现 fmt.Stringer 和 fmt.Formatter 接口:

type Point struct {
    X, Y int
}

// 实现 Stringer 接口
func (p Point) String() string {
    return fmt.Sprintf("(%d,%d)", p.X, p.Y)
}

// 实现 Formatter 接口
func (p Point) Format(f fmt.State, verb rune) {
    switch verb {
    case 'v':
        if f.Flag('+') {
            fmt.Fprintf(f, "Point{X:%d, Y:%d}", p.X, p.Y)
        } else {
            fmt.Fprintf(f, "(%d, %d)", p.X, p.Y)
        }
    case 'P':
        fmt.Fprintf(f, "Point at (%d, %d)", p.X, p.Y)
    default:
        fmt.Fprintf(f, "%%!%c(Point=%v)", verb, p)
    }
}

func main() {
    p := Point{X: 1, Y: 2}
    fmt.Println(p)      // 调用 String()
    fmt.Printf("%v\n", p) // 调用 Format()
    fmt.Printf("%+v\n", p)
    fmt.Printf("%P\n", p)
    fmt.Printf("%d\n", p) // 错误格式化
}

错误处理

fmt 包还提供了一些错误处理工具:

// 创建带格式的错误
err := fmt.Errorf("user %q (id %d) not found", "alice", 42)

// 错误值可以包含更多上下文
if _, ok := err.(interface{ Unwrap() error }); ok {
    fmt.Println("Error implements Unwrap()")
}

性能考虑

// 多次拼接字符串时,使用 fmt.Fprint 比 fmt.Sprintf 更高效
var sb strings.Builder
for i := 0; i < 100; i++ {
    fmt.Fprintf(&sb, "%d", i)
}

总结

fmt 包是 Go 语言中非常强大和灵活的格式化 I/O 工具。掌握它的格式化动词和各种函数,可以让你写出更加清晰和高效的输出代码。无论是简单的打印调试还是复杂的格式化需求,fmt 包都能胜任。

文末预告

下一期我们将深入学习 Go 语言的 net/http 标准库,探讨 HTTP 客户端和服务器的实现原理,以及如何构建高效的 Web 应用。敬请期待!

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇