62、Go 语言基础 - fmt 包详解 (基础篇完结)
hi,我是温新
fmt
包是 Go 标准库中用于格式化输入和输出的重要包。它提供了一组函数和方法,可以用于打印、扫描、格式化和处理各种数据类型。
向外输出
fmt.Print()
用于输出文本的函数。它可以将指定的文本参数打印到标准输出(通常是终端)。
func Print(a ...interface{}) (n int, err error)
-
a ...interface{}
: 可变参数,允许传递一个或多个参数。这些参数可以是不同类型的数据,如字符串、整数、浮点数等。
返回值:
-
n int
: 打印的字符数(字节数)。 -
err error
: 错误信息,如果没有错误发生,将为nil
。
func main() {
name := "王美丽"
age := 19
// 使用 fmt.Print() 输出文本到标准输出
fmt.Print("Name: ", name, ", Age: ", age)
}
Println
fmt.Println()
用于输出文本的函数,类似于 fmt.Print()
,但它在输出的最后会自动添加一个换行符,以使下一次输出从新的一行开始
func Println(a ...interface{}) (n int, err error)
func main() {
name := "王小丽"
age := 18
// 使用 fmt.Println() 输出文本到标准输出
fmt.Println("Name:", name)
fmt.Println("Age:", age)
}
Fprint
fmt.Fprint()
函数,用于将格式化的文本输出到指定的 io.Writer
接口。
与 fmt.Print()
和 fmt.Println()
不同,Fprint
不会输出到标准输出,而是可以将文本输出到任何实现了 io.Writer
接口的地方,例如文件、网络连接或缓冲区。
func Fprint(w io.Writer, a ...interface{}) (n int, err error)
-
w io.Writer
: 表示输出的目标,通常是一个实现了io.Writer
接口的对象,可以是文件、网络连接等。 -
a ...interface{}
: 可变参数,允许传递一个或多个参数。这些参数可以是不同类型的数据,如字符串、整数、浮点数等。
返回值:
-
n int
: 表示写入的字节数。 -
err error
: 表示写入时可能出现的错误
package main
import (
"fmt"
"os"
)
func main() {
file, err := os.Create("output.txt")
if err != nil {
fmt.Println("Error creating file:", err)
return
}
defer file.Close()
name := "Alice"
age := 30
// 使用 fmt.Fprint() 将文本输出到文件
n, err := fmt.Fprint(file, "Name:", name, "\n")
if err != nil {
fmt.Println("Error writing to file:", err)
return
}
fmt.Printf("Wrote %d bytes to the file.\n", n)
// 将文本输出到标准输出
fmt.Fprint(os.Stdout, "Age:", age, "\n")
}
Sprint
fmt.Sprint()
函数,用于将格式化的文本作为一个字符串返回,而不进行实际的输出。
func Sprint(a ...interface{}) string
-
a ...interface{}
: 可变参数,允许传递一个或多个参数。这些参数可以是不同类型的数据,如字符串、整数、浮点数等。 - 返回值是一个字符串,包含了将参数格式化后得到的文本。
package main
import "fmt"
func main() {
name := "王美丽"
age := 19
// 使用 fmt.Sprint() 将文本格式化为字符串
result := fmt.Sprint("Name:", name, ", Age:", age)
// 打印结果
fmt.Println("Result:", result)
}
Errorf
fmt.Errorf()
函数,用于创建一个新的 error
类型值,该值包含了格式化的错误信息。
func Errorf(format string, a ...interface{}) error
参数和返回值的含义如下:
-
format string
: 一个字符串,用于指定错误信息的格式。 -
a ...interface{}
: 可变参数,允许传递一个或多个参数,这些参数将替代format
字符串中的相应占位符。 - 返回值是一个
error
类型值,包含了格式化后的错误信息。
func main() {
result, err := divide(10, 0)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Result:", result)
}
}
func divide(a, b int) (int, error) {
if b == 0 {
return 0, fmt.Errorf("division by zero")
}
return a / b, nil
}
获取输入
Go语言fmt
包下有fmt.Scan
、fmt.Scanf
、fmt.Scanln
三个函数,可以在程序运行过程中从标准输入获取用户的输入。
Scan
fmt.Scan
函数用于从标准输入或其他实现了 io.Reader
接口的输入源中读取数据并将其解析为不同类型的值。
func Scan(a ...interface{}) (n int, err error)
func main() {
var num int
fmt.Print("请输入一个整数: ")
_, err := fmt.Scan(&num) // 读取一个整数
if err != nil {
fmt.Println("输入错误:", err)
return
}
fmt.Printf("你输入的整数是: %d\n", num)
}
Scanf
fmt.Scanf
函数用于从标准输入或其他实现了 io.Reader
接口的输入源中按照格式化字符串指定的格式读取数据并将其解析为不同类型的值。
func Scanf(format string, a ...interface{}) (n int, err error)
-
fmt.Scanf
函数接受两个参数:格式化字符串format
和一系列参数a
,这些参数是指向变量的指针,用于存储从输入源中解析出的数据。 -
format
参数包含与输入数据的格式匹配的格式化占位符,例如,%d
用于整数,%f
用于浮点数,%s
用于字符串。
func main() {
var num1, num2 int
fmt.Print("请输入两个整数,用空格分隔: ")
n, err := fmt.Scanf("%d %d", &num1, &num2)
if err != nil {
fmt.Println("输入错误:", err)
return
}
if n != 2 {
fmt.Println("需要输入两个整数。")
return
}
sum := num1 + num2
fmt.Printf("两个整数的和为: %d\n", sum)
}
Scanln
Scanln
用于从标准输入或其他实现了 io.Reader
接口的输入源中读取数据并将其解析为不同类型的值。
func Scanln(a ...interface{}) (n int, err error)
-
fmt.Scanln
函数接受一系列参数a
,这些参数是指向变量的指针,用于存储从输入源中解析出的数据。 - 函数会尝试从输入源中按顺序读取数据并将其解析为对应类型的值,直到遇到换行符(
\n
)或者达到输入流的结尾。 - 函数返回成功读取的数据数量
n
和可能出现的错误err
。
func main() {
var num1, num2 int
fmt.Println("请输入两个整数:")
n, err := fmt.Scanln(&num1, &num2)
if err != nil {
fmt.Println("输入错误:", err)
return
}
if n != 2 {
fmt.Println("需要输入两个整数。")
return
}
sum := num1 + num2
fmt.Printf("两个整数的和为: %d\n", sum)
}
NewReader
bufio.NewReader
用于创建一个带有缓冲区的读取器,以提高文件或其他输入源的读取性能。
func NewReader(rd io.Reader) *Reader
-
NewReader
接受一个io.Reader
类型的参数rd
,这个参数是你要从中读取数据的输入源。 - 函数返回一个
*Reader
类型的指针,它表示一个带有缓冲区的读取器。
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
// 从标准输入生成读对象
reader := bufio.NewReader(os.Stdin)
fmt.Print("请输入内容:")
// 读到换行
text, _ := reader.ReadString('\n')
text = strings.TrimSpace(text)
fmt.Printf("%#v\n", text)
}
格式化占位符
通用占位符
占位符 | 说明 |
---|---|
%v | 值的默认格式表示 |
%+v | 类似%v,但输出结构体时会添加字段名 |
%#v | 值的Go语法表示 |
%T | 打印值的类型 |
%% | 百分号 |
fmt.Printf("%v\n", 100)
fmt.Printf("%v\n", false)
o := struct{ name string }{"王美丽"}
fmt.Printf("%v\n", o)
fmt.Printf("%#v\n", o)
fmt.Printf("%T\n", o)
fmt.Printf("100%%\n")
布尔型
占位符 | 说明 |
---|---|
%t | true或false |
整型
占位符 | 说明 |
---|---|
%b | 表示为二进制 |
%c | 该值对应的unicode码值 |
%d | 表示为十进制 |
%o | 表示为八进制 |
%x | 表示为十六进制,使用a-f |
%X | 表示为十六进制,使用A-F |
%U | 表示为Unicode格式:U+1234,等价于"U+%04X" |
%q | 该值对应的单引号括起来的go语法字符字面值,必要时会采用安全的转义表示 |
n := 100
fmt.Printf("%b\n", n)
fmt.Printf("%c\n", n)
fmt.Printf("%d\n", n)
fmt.Printf("%o\n", n)
fmt.Printf("%x\n", n)
fmt.Printf("%X\n", n)
浮点数与复数
占位符 | 说明 |
---|---|
%b | 无小数部分、二进制指数的科学计数法,如-123456p-78 |
%e | 科学计数法,如-1234.456e+78 |
%E | 科学计数法,如-1234.456E+78 |
%f | 有小数部分但无指数部分,如123.456 |
%F | 等价于%f |
%g | 根据实际情况采用%e或%f格式(以获得更简洁、准确的输出) |
%G | 根据实际情况采用%E或%F格式(以获得更简洁、准确的输出) |
f := 3.14
fmt.Printf("%b\n", f)
fmt.Printf("%e\n", f)
fmt.Printf("%E\n", f)
fmt.Printf("%f\n", f)
fmt.Printf("%g\n", f)
fmt.Printf("%G\n", f)
字符串和[]byte
占位符 | 说明 |
---|---|
%s | 直接输出字符串或者[]byte |
%q | 该值对应的双引号括起来的go语法字符串字面值,必要时会采用安全的转义表示 |
%x | 每个字节用两字符十六进制数表示(使用a-f |
%X | 每个字节用两字符十六进制数表示(使用A-F) |
s := "王美丽"
fmt.Printf("%s\n", s)
fmt.Printf("%q\n", s)
fmt.Printf("%x\n", s)
fmt.Printf("%X\n", s)
指针
占位符 | 说明 |
---|---|
%p | 表示为十六进制,并加上前导的0x |
num := 100
fmt.Printf("%p\n", &num)
fmt.Printf("%#p\n", &num)
宽度标识符
在 Go 中,宽度标识符是指在格式化字符串中用来控制字段的宽度的部分
以下是一些示例:
-
%5s
: 字符串字段的宽度为 5 个字符。如果字符串不够 5 个字符,将用空格在字符串前面进行填充。 -
%10d
: 整数字段的宽度为 10 个字符。如果整数不够 10 个字符,将用空格在整数前面进行填充。 -
%3.2f
: 浮点数字段的宽度为 3 个字符,小数点后保留 2 位小数。
占位符 | 说明 |
---|---|
%f | 默认宽度,默认精度 |
%9f | 宽度9,默认精度 |
%.2f | 默认宽度,精度2 |
%9.2f | 宽度9,精度2 |
%9.f | 宽度9,精度0 |
n := 12.34
fmt.Printf("%f\n", n)
fmt.Printf("%9f\n", n)
fmt.Printf("%.2f\n", n)
fmt.Printf("%9.2f\n", n)
fmt.Printf("%9.f\n", n)
其他flag
占位符 | 说明 |
---|---|
‘+’ | 总是输出数值的正负号;对%q(%+q)会生成全部是ASCII字符的输出(通过转义); |
’ ' | 对数值,正数前加空格而负数前加负号;对字符串采用%x或%X时(% x或% X)会给各打印的字节之间加空格 |
‘-’ | 在输出右边填充空白而不是默认的左边(即从默认的右对齐切换为左对齐); |
‘#’ | 八进制数前加0(%#o),十六进制数前加0x(%#x)或0X(%#X),指针去掉前面的0x(%#p)对%q(%#q),对%U(%#U)会输出空格和单引号括起来的go字面值; |
‘0’ | 使用0而不是空格填充,对于数值类型会把填充的0放在正负号后面; |
s := "王美丽"
fmt.Printf("%s\n", s)
fmt.Printf("%5s\n", s)
fmt.Printf("%-5s\n", s)
fmt.Printf("%5.7s\n", s)
fmt.Printf("%-5.7s\n", s)
fmt.Printf("%5.2s\n", s)
fmt.Printf("%05s\n", s)