fmt 包入門指南
相信很多人入坑 Go 語言都是從官網的fmt.Println("Hello World")
入門的,這篇文章帶你好好了解一下fmt
包還可以做哪些事情。
在 Go 語言中,我們經常使用 fmt 包進行格式化輸入輸出操作。雖然大多數時候我們只會使用 Print...、Sprint... 和 Errorf 等少數函數,也只會用到一些常見的佔位符,但這並不代表我們不需要了解 fmt 包的其他特性。
fmt 包概述#
fmt 包實現了類似於 C 語言的格式化輸入輸出函數。
Print 系列函數#
func Print(a ...interface{}) (n int, err error)
func Printf(format string, a ...interface{}) (n int, err error)
func Println(a ...interface{}) (n int, err error)
Print 系列函數會將內容輸出到標準輸出,Print 函數直接輸出內容,Printf 支持格式化輸出,Println 每次輸出的內容都會加一個換行符。
例如:
fmt.Print("123")
fmt.Printf("%d", 456)
fmt.Print("789")
fmt.Printf("%d\n", 123)
fmt.Println("123")
fmt.Println("456")
輸出:
123456789123
123
456
Sprint 系列函數#
func Sprint(a ...interface{}) string
func Sprintf(format string, a ...interface{}) string
func Sprintln(a ...interface{}) string
Sprint 系列函數會將內容輸出為字符串,區別在於 Sprint 直接輸出內容,Sprintf 將後面的內容映射到對應的佔位符,Sprintln 會在內容後面添加一個換行符。
例如:
s1 := fmt.Sprint("123")
s2 := fmt.Sprintf("name:%s,age:%d", "Lixin", 21)
s3 := fmt.Sprintln("456")
fmt.Println(s1, s2, s3)
輸出:
123 name:Lixin,age:21 456
Fprint 系列函數#
func Fprint(w io.Writer, a ...interface{}) (n int, err error)
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error)
func Fprintln(w io.Writer, a ...interface{}) (n int, err error)
Fprint 系列函數會將內容輸出到實現了 io.Writer 接口的變量,常見用法是向文件中寫入內容,也可以向終端輸出內容(很少見)。
例如,向標準輸出寫入內容:
fmt.Fprintln(os.Stdout, "向標準輸出寫入內容")
fileObj, err := os.OpenFile("./output.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
panic(err)
}
name := "Lixin"
// 向打開的文件句柄中寫入內容
fmt.Fprintf(fileObj, "往文件中寫入信息\nname: %s\nage: %d", name, 21)
輸出的內容為:
向標準輸出寫入內容
文件 output.txt
的內容為:
往文件中寫入信息
name: Lixin
age: 21
Errors#
Errorf 類似於 Printf,但返回一個包含該字符串的錯誤。
通常我們
會返回這樣的錯誤:
var err error
// ...
return fmt.Errorf("Error: %v", err)
Scan 系列函數#
func Scan(a ...interface{}) (n int, err error)
func Scanf(format string, a ...interface{}) (n int, err error)
func Scanln(a ...interface{}) (n int, err error)
Scan 系列函數用於從標準輸入中掃描文本,並根據 format 參數指定的格式將對應的值映射到 a... 的參數中。
Scan 函數根據空格來區分輸入的值,Scanf 根據 format 來區分值,Scanln 根據回車來停止掃描。
例如:
var name string
var age int
fmt.Scanln(&name, &age)
fmt.Printf("name: %s, age: %d", name, age)
輸入 Lixin 21
,輸出:
name: Lixin, age: 21
Scanf 的示例:
var name string
var age int
fmt.Scanf("name:%s age:%d", &name, &age)
fmt.Printf("name: %s, age: %d", name, age)
輸入 name:Lixin age:21
,輸出:
name: Lixin, age: 21
Fscan 系列函數#
func Fscan(r io.Reader, a ...interface{}) (n int, err error)
func Fscanln(r io.Reader, a ...interface{}) (n int, err error)
func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error)
Fscan 系列函數可以從標準輸入中讀取數據,例如文件或命令行中的輸入。
如果想從文件中讀取內容:
var s string
f, _ := os.OpenFile("./output.txt", os.O_CREATE|os.O_RDWR, 0644)
reader := bufio.NewReader(f)
fmt.Fscan(reader, &s)
fmt.Printf("讀取的字符串是:%s", s)
如果文件 output.txt
的內容是 file.Outputn ame: Lixinage: 21
,則輸出為 讀取的字符串是:file.Outputn
,因為 Fscan 默認使用空格作為分隔符,無法識別空格後的內容。
如果想從標準輸入中讀取內容,可以使用以下代碼:
var s string
reader := bufio.NewReader(os.Stdin)
fmt.Fscan(reader, &s)
fmt.Printf("你的輸入內容是:%s", s)
輸入 Hello, Lixin
,輸出 你的輸入內容是:Hello
,同樣因為該函數無法識別空格。
Fscanln 函數是根據換行符來停止掃描的,Fscanf 類似於 Scanf,用於映射對應的換行符,這兩個函數用法類似。
另外,這裡提一下 bufio 包中的 ReadString 函數,用於從指定的 io.Reader 中讀取一行字符串,直到遇到指定的分隔符為止。函數簽名如下:
func (b *Reader) ReadString(delim byte) (string, error)
例如,如果想讀取文件 output.txt
的第一行,並以空格作為分隔符,可以這樣寫:
f, _ := os.OpenFile("./output.txt", os.O_RDWR, 0644)
reader := bufio.NewReader(f)
line, err := reader.ReadString(' ')
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("讀取的字符串是:%s", line)
如果文件 output.txt
的內容是 file.Outputn ame: Lixinage: 21
,則輸出為 讀取的字符串是:file.Outputn
,因為 ReadString 在遇到空格時停止讀取。
Sscan 系列函數#
func Sscan(str string, a ...interface{}) (n int, err error)
func Sscanln(str string, a ...interface{}) (n int, err error)
func Sscanf(str string, format string, a ...interface{}) (n int, err error)
Sscan 是用於從字符串中讀取數據並格式化到指定變量中的函數。
例如:
str := "1 2 3"
var a, b, c int
n, err := fmt.Sscan(str, &a, &b, &c)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("讀取了 %d 個數,分別是:%d,%d,%d", n, a, b, c)
運行該函數,輸出:
讀取了 3 個數,分別是:1,2,3
在 Go 語言的 fmt
包中,有一些常見的佔位符可以用於格式化輸出。以下是一些常用的佔位符及其使用方式:
%v
:通用的佔位符,可以用於格式化任意類型的值。它會根據值的類型自動選擇適當的格式。%d
:用於格式化整數類型(包括有符號整數和無符號整數)。%f
:用於格式化浮點數類型。%s
:用於格式化字符串類型。%t
:用於格式化布爾類型。%c
:用於格式化字符類型。%p
:用於格式化指針類型。
以下是一些示例說明如何使用這些佔位符:
name := "Lixin"
age := 21
pi := 3.14159
isStudent := true
fmt.Printf("Name: %s, Age: %d\n", name, age) // 輸出:Name: Lixin, Age: 21
fmt.Printf("Pi: %.2f\n", pi) // 輸出:Pi: 3.14
fmt.Printf("Is student: %t\n", isStudent) // 輸出:Is student: true
在格式化字符串中,佔位符用百分號 %
後跟一個字母表示。在 %d
和 %f
等佔位符後可以加上一些附加參數來控制格式化的方式。例如,%f
佔位符可以使用 .2
來限制浮點數只保留兩位小數。
除了 Printf
函數,還有其他的函數如 Sprintf
和 Fprintf
也可以使用這些佔位符。Sprintf
函數將格式化的結果作為字符串返回,而 Fprintf
函數將格式化的結果寫入一個指定的 io.Writer
。
result := fmt.Sprintf("Name: %s, Age: %d", name, age)
fmt.Println(result) // 輸出:Name: Lixin, Age: 21
file, _ := os.Create("output.txt")
fmt.Fprintf(file, "Name: %s, Age: %d", name, age)
file.Close()
總結#
這些是 fmt
包中常見的佔位符和使用方式。具體可以去看官網頁面,裡面寫的很詳細