fmt 包是 Go 语言的标准库之一,提供了多种格式化和输出文本的函数。下面是几种常见函数使用方式。

Printf

Printf可以说是使用最广泛的函数,没有之一。官方文档入口,下面列举常见用法。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//整型
a := 15
fmt.Printf("a = %b\n", a) //a = 1111
fmt.Printf("%%\n")        //只输出一个%

//字符
ch := 'a'
fmt.Printf("ch = %c, %c\n", ch, 97) //a, a

//浮点型
f := 3.14
fmt.Printf("f = %f, %g\n", f, f) //f = 3.140000, 3.14
fmt.Printf("f type = %T\n", f)   //f type = float64

//复数类型
v := complex(3.2, 12)
fmt.Printf("v = %f, %g\n", v, v) //v = (3.200000+12.000000i), (3.2+12i)
fmt.Printf("v type = %T\n", v)   //v type = complex128

//布尔类型
fmt.Printf("%t, %t\n", true, false) //true, false

//字符串
str := "hello go"
fmt.Printf("str = %s\n", str) //str = hello go

浮点型小数点保留

要保留两位小数,可以使用 %.2f 这样的格式说明符,2表示要保留的小数点位数。

1
fmt.Printf("%.2f\n", 3.14159)  // 输出 3.14

也可以使用 Go 语言的内置函数 math.Round 来四舍五入浮点数。例如:

1
2
3
4
5
import "math"

x := 3.14159
rounded := math.Round(x*100) / 100
fmt.Println(rounded)  // 输出 3.14

如果只想保留整数部分,可以使用 math.Trunc 函数来截断小数部分:

1
2
truncated := math.Trunc(x)
fmt.Println(truncated)  // 输出 3

格式化对齐

格式化对齐需要在%符号后面指定要对齐的长度。使用 - 字符表示左对齐。例如:

1
2
fmt.Printf("%-10s %s\n", "Apple", "100")  // 左对齐,输出 "Apple      100"
fmt.Printf("%10s %s\n", "Apple", "100")  // 右对齐,输出 "     Apple 100"

如果要输出浮点数,一般还需要指定小数位数。例如:

1
2
fmt.Printf("%-10s %10.2f\n", "Apple", 3.14159)  // 左对齐,输出 "Apple          3.14"
fmt.Printf("%10s %-10.2f\n", "Apple", 3.14159)  // 右对齐,输出 "     Apple 3.14     "

Fprintf

fmt 包中的 Fprintf 函数可以将文本输出到指定的输出流中。它的用法类似于 Printf 函数,但是需要提供一个 io.Writer 类型的参数,用于指定输出流。

例如,你可以使用 Fprintf 函数将文本输出到标准输出中:

1
fmt.Fprintf(os.Stdout, "Hello, %s!", "world")

也可以使用 Fprintf函数将文本输出到文件中:

1
2
3
4
5
6
7
8
file, err := os.Create("output.txt")
if err != nil {
    fmt.Println(err)
    return
}
defer file.Close()

fmt.Fprintf(file, "Hello, %s!", "world")

还可以使用 Fprintf 函数将文本输出到网络连接中:

1
2
3
4
5
6
7
8
conn, err := net.Dial("tcp", "localhost:8080")
if err != nil {
    fmt.Println(err)
    return
}
defer conn.Close()

fmt.Fprintf(conn, "Hello, %s!", "world")

Sprintf

fmt 包中的 Sprintf 函数可以将文本格式化为字符串。它的用法类似于 Printf 函数,但是会将输出作为字符串返回。

你可以使用 Sprintf 函数将数字格式化为字符串:

1
s := fmt.Sprintf("%d", 123)  // s 的值为 "123"

Scanf

fmt 包中的 Scanf 函数可以从标准输入中读取文本。它接受一个格式字符串和一个变量的列表,根据格式字符串将输入值转换为变量。

你可以使用 Scanf 函数读取一个字符串:

1
2
3
4
fmt.Print("Enter a string: ")
var s string
fmt.Scanf("%s\n", &s)
fmt.Println("You entered:", s)

也可以使用 Scanf 函数读取多个值:

1
2
3
4
5
fmt.Print("Enter an integer and a float: ")
var i int
var f float64
fmt.Scanf("%d %f\n", &i, &f)
fmt.Println("You entered:", i, f)

请注意,Scanf 函数会按照格式字符串的顺序将输入值转换为变量。

Fscanf

fmt 包中的 Fscanf 函数可以从一个 io.Reader 类型的变量读取输入并根据格式字符串将输入值转换为变量。它的用法类似于 Scanf 函数,但是你可以指定输入来源。

例如,你可以使用 Fscanf 函数从标准输入读取输入:

1
2
3
4
5
6
fmt.Print("Enter an integer, a float, and a string: ")
var i int
var f float64
var s string
fmt.Fscanf(os.Stdin, "%d %f %s\n", &i, &f, &s)
fmt.Println("You entered:", i, f, s)

Stringer

fmt 包中的 Stringer 接口表示一种可以返回其字符串表示的类型。如果一个类型实现了 Stringer 接口,那么在调用 fmt 包中的输出函数(例如 PrintPrintlnPrintf)时,会调用这个类型的 String 方法,并将返回值作为字符串输出。

例如,你可以为自定义类型 Person 实现 Stringer 接口,使得在调用 fmt 包中的输出函数时,能够将 Person 类型的值输出为指定的字符串。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
type Person struct {
    Name string
    Age  int
}

func (p Person) String() string {
    return fmt.Sprintf("%s is %d years old", p.Name, p.Age)
}

p := Person{Name: "Alice", Age: 30}
fmt.Println(p)  // 输出 "Alice is 30 years old"

请注意,如果一个类型实现了 Stringer 接口,那么在调用输出函数时,会忽略其他的格式说明符。例如:

1
2
3
fmt.Printf("%v\n", p)  // 输出 "Alice is 30 years old"
fmt.Printf("%+v\n", p)  // 输出 "Alice is 30 years old"
fmt.Printf("%#v\n", p)  // 输出 "main.Person{Name:\"Alice\", Age:30}"