GoClub Pro

Go-fmt

最近更新:2026-10-24
本页是手写/批注类笔记,直接按原始笔记截图呈现(转成文字会乱序);原始笔记文件见「Go语言相关笔记」页的原始链接。
onenote-go-fmt 原始笔记截图 1

附件文档全文(fmt )#

fmt包详解

你想详细了解 Go 语言中 fmt 包的使用方法和核心功能,这是 Go 开发中最基础也最常用的包之一,掌握它能帮你高效处理输入输出、格式化字符串等场景。

一、fmt 包核心作用

fmt 包(format 的缩写)是 Go 标准库中用于格式化输入/输出的核心包,主要功能包括:

  • 向控制台/文件输出格式化内容(如 Print/Println/Printf);
  • 从控制台读取格式化输入(如 Scan/Scanln/Scanf);
  • 格式化字符串(如 Sprint/Sprintf);
  • 自定义类型的格式化输出(实现 Stringer/Formatter 接口)。

二、核心函数分类与使用示例

1. 输出类函数(最常用)

这类函数用于将内容输出到标准输出(控制台)或自定义 io.Writer,核心区别在于是否换行、是否支持格式化占位符。

函数

功能说明

示例

输出结果

Print

直接输出内容,不自动换行

fmt.Print("hello", "go")

hellogo

Println

输出内容后自动换行,多个参数间加空格

fmt.Println("hello", "go")

hello go(换行)

Printf

按占位符格式化输出,需手动控制换行(\n)

fmt.Printf("hello %s\n", "go")

hello go(换行)

Fprint

输出到指定 io.Writer(如文件)

fmt.Fprint(os.Stdout, "hello")

控制台输出 hello

Sprint

格式化内容并返回字符串(不输出)

s := fmt.Sprint("hello", "go")

s = "hellogo"

Sprintf

按占位符格式化并返回字符串

s := fmt.Sprintf("hello %s", "go")

s = "hello go"

核心占位符说明(Printf/Sprintf 必备):

占位符

适用类型

示例

说明

%v

任意类型

fmt.Printf("%v", 123)

按值的默认格式输出

%+v

结构体

fmt.Printf("%+v", user)

输出结构体字段名+值

%#v

任意类型

fmt.Printf("%#v", "go")

输出值的 Go 语法表示

%T

任意类型

fmt.Printf("%T", 3.14)

输出值的类型

%d

整数(十进制)

fmt.Printf("%d", 010)

输出 8(八进制转十进制)

%s

字符串/字节切片

fmt.Printf("%s", []byte("go"))

输出 go

%f

浮点数

fmt.Printf("%.2f", 3.1415)

输出 3.14(保留2位)

%p

指针

fmt.Printf("%p", &x)

输出指针内存地址(十六进制)

示例代码:

Go
package main

import "fmt"

type User struct {
Name string
Age int
}

func main() {
// 基础输出
fmt.Print("基础输出:")
fmt.Println("hello", "go") // 自动加空格+换行
fmt.Printf("格式化输出:%s 年龄 %d\n", "张三", 20)

// 结构体格式化
user := User{Name: "李四", Age: 25}
fmt.Printf("默认格式:%v\n", user) // {李四 25}
fmt.Printf("带字段名:%+v\n", user) // {Name:李四 Age:25}
fmt.Printf("Go语法:%#v\n", user) // main.User{Name:"李四", Age:25}

// 类型和值
num := 3.14
fmt.Printf("值:%v,类型:%T\n", num, num) // 值:3.14,类型:float64

// 字符串格式化(返回字符串不输出)
s := fmt.Sprintf("姓名:%s,年龄:%d", "王五", 30)
fmt.Println("格式化字符串:", s) // 格式化字符串:姓名:王五,年龄:30
}

2. 输入类函数

用于从标准输入(控制台)读取用户输入,并解析到变量中。

函数

功能说明

示例

Scan

从输入读取值,以空格/换行分隔,赋值给变量

fmt.Scan(&name, &age)

Scanln

同 Scan,但遇到换行就停止读取

fmt.Scanln(&name)

Scanf

按占位符格式读取输入

fmt.Scanf("姓名:%s 年龄:%d", &name, &age)

Sscan

从字符串读取值(而非控制台)

fmt.Sscan("张三 20", &name, &age)

示例代码:

Go
package main

import "fmt"

func main() {
var name string
var age int

// 读取控制台输入(输入格式:张三 20,回车)
fmt.Print("请输入姓名和年龄:")
fmt.Scan(&name, &age)
fmt.Printf("你输入的:姓名=%s,年龄=%d\n", name, age)

// 按格式读取
var addr string
fmt.Print("请按格式输入地址(格式:地址:XXX):")
fmt.Scanf("地址:%s", &addr)
fmt.Printf("地址:%s\n", addr)
}

3. 自定义格式化(Stringer 接口)

如果想让自定义类型(如结构体)在 Print/Println/Printf 时输出自定义格式,可实现 fmt.Stringer 接口(仅需实现 String() string 方法)。

示例代码:

Go
package main

import "fmt"

type Product struct {
ID int
Price float64
}

// 实现 fmt.Stringer 接口
func (p Product) String() string {
return fmt.Sprintf("商品[ID:%d,价格:%.2f元]", p.ID, p.Price)
}

func main() {
p := Product{ID: 1001, Price: 99.9}
fmt.Println(p) // 输出:商品[ID:1001,价格:99.90元]
fmt.Printf("%v\n", p) // 同样触发自定义 String() 方法
}

三、常见注意事项

  1. Printf 必须保证占位符数量与参数数量一致,否则会报错(如 fmt.Printf("%s %d", "a") 会 panic);
  2. Scan 读取时,变量必须传指针(否则无法修改变量值);
  3. 浮点数格式化 %f 可通过 %.2f 控制小数位数,避免精度冗余;
  4. String() 方法中避免再次调用 fmt.Print(p)(会递归调用 String(),导致死循环)。

总结

  1. fmt 包核心是格式化输入输出,最常用的是 Println(简单输出)、Printf(格式化输出)、Sprintf(格式化字符串);
  2. 占位符是 Printf/Sprintf 的核心,%v(通用值)、%+v(结构体带字段名)、%T(类型)是高频使用的占位符;
  3. 自定义类型可通过实现 fmt.Stringer 接口,控制格式化输出的样式,让输出更贴合业务需求。

|(注:文档部分内容可能由 AI 生成)

附件原文:onenote-go-fmt-fmt_.docx(点击下载)

转换文字版(供搜索 / 复制)


func Print(a ...interface{}) (n int, err error)

func Println(a ...interface{}) (n int, err error)

func Printf(format string, a ...interface{}) (n int, err error)

func Sprintf(format string, a ...interface{}) string

// 创建或打开一个文件

file, err := os.Create("output.txt")

if err != nil {

fmt.Println("文件创建失败:", err)

return

}

defer file.Close()

 

// 使用 Fprintf 将内容写入文件

name := "小明"

age := 20

_, err = fmt.Fprintf(file, "我的名字是 %s,今年 %d 岁。\n", name, age)

if err != nil {

fmt.Println("写入文件失败:", err)

return

}

fmt.Println("内容已成功写入文件")

 

 

func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error)

func Scan(a ...interface{}) (n int, err error)

func Scanln(a ...interface{}) (n int, err error)

func Scanf(format string, a ...interface{}) (n int, err error)

file, err = os.Open("data.txt")

if err != nil {

fmt.Println("无法打开文件:", err)

return

}

defer file.Close()

 

var name string

var age int

 

// 从文件中读取数据

for {

_, err := fmt.Fscanf(file, "%s %d\n", &name, &age)

if err != nil {

break // 读取完毕或出现错误

}

fmt.Printf("姓名: %s, 年龄: %d\n", name, age)

}

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 Errorf(format string, a ...interface{}) error

// 自定义函数,用于模拟错误场景

func divide(a, b float64) (float64, error) {

if b == 0 {

// 使用 fmt.Errorf 创建格式化的错误

return 0, fmt.Errorf("不能将 %f 除以 0", a)

}

return a / b, nil

}

 

内容反馈

发现错误或想补充内容?

GoClub Pro 是静态知识库,评论功能不再加载第三方脚本。你可以在 GitHub 仓库提交 Issue,反馈会直接进入项目协作流程。

提交 GitHub 反馈