Golang fmt.Fprintf 函数
最后修改时间 2025 年 5 月 8 日
本教程将解释如何在 Go 中使用 fmt.Fprintf 函数。我们将通过将格式化输出写入各种 io.Writer 实现的实际示例,涵盖格式化输出基础知识。
fmt.Fprintf 函数根据格式说明符进行格式化,并写入 io.Writer。它类似于 fmt.Printf,但写入指定的 writer 而不是标准输出。
在 Go 中,fmt.Fprintf 用于将格式化输出写入文件、缓冲区、网络连接或任何实现 io.Writer 接口的类型。它返回写入的字节数以及遇到的任何写入错误。
基本的 Fprintf 示例
fmt.Fprintf 最简单的用法是将格式化文本写入标准输出。此示例演示了基本的格式化打印。
注意: os.Stdout 实现 io.Writer,使其兼容。
package main
import (
"fmt"
"os"
)
func main() {
name := "Alice"
age := 28
n, err := fmt.Fprintf(os.Stdout, "%s is %d years old\n", name, age)
if err != nil {
fmt.Println("Error:", err)
}
fmt.Printf("Wrote %d bytes\n", n)
}
该示例将格式化输出写入标准输出。它显示写入的字节数并处理写入操作可能产生的错误。
使用 Fprintf 写入文件
fmt.Fprintf 可以将格式化文本写入文件。此示例展示了如何创建文件并向其中写入格式化数据。
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()
items := []string{"apple", "banana", "cherry"}
for i, item := range items {
fmt.Fprintf(file, "Item %d: %s\n", i+1, item)
}
fmt.Println("Data written to file successfully")
}
该示例创建了一个文件,并向其中写入格式化的行。每行包含切片中的项目编号和名称。完成后文件会被正确关闭。
写入 bytes.Buffer
fmt.Fprintf 可以写入内存缓冲区。此示例使用 bytes.Buffer 在使用格式化输出之前收集它。
package main
import (
"bytes"
"fmt"
)
func main() {
var buf bytes.Buffer
fmt.Fprintf(&buf, "Current temperature: %.1f°C\n", 23.5)
fmt.Fprintf(&buf, "Humidity: %d%%\n", 65)
fmt.Println("Buffer content:")
fmt.Println(buf.String())
}
该示例将格式化字符串写入 bytes.Buffer。缓冲区会收集输出,然后可以将其用作字符串或写入其他地方。
自定义写入器实现
任何实现 io.Writer 的类型都可以与 fmt.Fprintf 一起使用。此示例展示了一个自定义 writer,用于计算写入的字节数。
package main
import (
"fmt"
)
type ByteCounter struct {
count int
}
func (bc *ByteCounter) Write(p []byte) (n int, err error) {
bc.count += len(p)
return len(p), nil
}
func main() {
var counter ByteCounter
fmt.Fprintf(&counter, "Hello, %s!\n", "world")
fmt.Fprintf(&counter, "The answer is %d\n", 42)
fmt.Printf("Total bytes written: %d\n", counter.count)
}
ByteCounter 类型通过计算字节来实现 io.Writer。Fprintf 写入我们的自定义 writer,使我们能够跟踪写入的总字节数。
格式化不同的数据类型
fmt.Fprintf 支持各种数据类型的格式说明符。此示例演示了将不同数据类型格式化到 writer。
package main
import (
"fmt"
"os"
"time"
)
func main() {
now := time.Now()
pi := 3.1415926535
fmt.Fprintf(os.Stdout, "Boolean: %t\n", true)
fmt.Fprintf(os.Stdout, "Integer: %d\n", 42)
fmt.Fprintf(os.Stdout, "Float: %.2f\n", pi)
fmt.Fprintf(os.Stdout, "String: %s\n", "hello")
fmt.Fprintf(os.Stdout, "Time: %s\n", now.Format(time.RFC3339))
fmt.Fprintf(os.Stdout, "Pointer: %p\n", &pi)
}
该示例展示了常用的格式说明符:%t 用于布尔值,%d 用于整数,%f 用于浮点数,%s 用于字符串,%p 用于指针。每个都写入标准输出。
使用 Fprintf 进行错误处理
使用 fmt.Fprintf 写入时,正确的错误处理很重要。此示例演示了如何检查写入错误。
package main
import (
"fmt"
"os"
)
func main() {
// Simulate a write error by using a closed file
file, err := os.Create("test.txt")
if err != nil {
fmt.Println("Error creating file:", err)
return
}
file.Close()
n, err := fmt.Fprintf(file, "This should fail")
if err != nil {
fmt.Println("Write error:", err)
fmt.Println("Bytes written before error:", n)
return
}
fmt.Println("Write successful")
}
该示例故意写入一个已关闭的文件以演示错误处理。始终检查 Fprintf 返回的错误值以检测写入失败。
写入多个 writer
fmt.Fprintf 可以使用 io.MultiWriter 同时写入多个 writer。此示例同时写入文件和标准输出。
package main
import (
"fmt"
"io"
"os"
)
func main() {
file, err := os.Create("multi_output.txt")
if err != nil {
fmt.Println("Error creating file:", err)
return
}
defer file.Close()
multiWriter := io.MultiWriter(os.Stdout, file)
fmt.Fprintf(multiWriter, "Writing to multiple destinations\n")
fmt.Fprintf(multiWriter, "This appears in both places\n")
fmt.Println("Check multi_output.txt for the file content")
}
该示例使用 io.MultiWriter 在一次 Fprintf 调用中同时写入控制台和文件。这种模式对于日志记录或类似 tee 的输出很有用。
来源
本教程通过将格式化输出写入各种 io.Writer 实现的实际示例,涵盖了 Go 中的 fmt.Fprintf 函数。