最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go輸入與輸出格式化案例詳解

 更新時(shí)間:2025年10月10日 09:36:31   作者:數(shù)據(jù)知道  
Go語言的輸入與輸出格式化功能非常強(qiáng)大,通過 fmt 包和 bufio 包,可以滿足各種輸入輸出需求,本文給大家介紹Go輸入與輸出格式化案例,感興趣的朋友一起看看吧

一、Go語言輸入與輸出概述

Go語言中,輸入與輸出(I/O)操作主要通過 fmt 包和 bufio 包實(shí)現(xiàn)。fmt 包提供了基本的格式化輸入輸出功能,而 bufio 包則用于更高效的緩沖讀寫操作。

二、輸出格式化詳解

2.1 常用輸出函數(shù)

Go語言中,fmt 包提供了以下常用輸出函數(shù):

  • fmt.Print(a ...interface{}):打印參數(shù),不添加換行。
  • fmt.Println(a ...interface{}):打印參數(shù),自動(dòng)添加空格和換行。
  • fmt.Printf(format string, a ...interface{}):按格式化字符串打印。
  • fmt.Sprintf(format string, a ...interface{}):返回格式化后的字符串,不打印。
  • fmt.Fprintf(w io.Writer, format string, a ...interface{}):將格式化內(nèi)容寫入 io.Writer。

2.2 格式化動(dòng)詞(Verbs)

格式化動(dòng)詞用于控制輸出格式,常用動(dòng)詞包括:

動(dòng)詞說明
%v值的默認(rèn)格式
%+v類似 %v,但輸出結(jié)構(gòu)體時(shí)會(huì)添加字段名
%#v值的 Go 語法表示
%T值的類型
%%百分號
%d十進(jìn)制整數(shù)
%b二進(jìn)制整數(shù)
%x十六進(jìn)制整數(shù)(小寫)
%f浮點(diǎn)數(shù)
%s字符串
%p指針地址

2.3 案例

package main
import (
	"fmt"
	"os"
)
type Person struct {
	Name string
	Age  int
}
func main() {
	// 基本輸出
	fmt.Print("Hello, ")
	fmt.Println("World!")
	// 格式化輸出
	name := "Alice"
	age := 25
	fmt.Printf("Name: %s, Age: %d\n", name, age)
	// 結(jié)構(gòu)體格式化
	person := Person{Name: "Bob", Age: 30}
	fmt.Printf("Person: %v\n", person)         // 輸出: Person: {Bob 30}
	fmt.Printf("Person: %+v\n", person)        // 輸出: Person: {Name:Bob Age:30}
	fmt.Printf("Person: %#v\n", person)        // 輸出: Person: main.Person{Name:"Bob", Age:30}
	// 返回格式化字符串
	formattedStr := fmt.Sprintf("Name: %s, Age: %d", name, age)
	fmt.Println("Formatted string:", formattedStr)
	// 寫入文件
	file, err := os.Create("output.txt")
	if err != nil {
		fmt.Println("Error creating file:", err)
		return
	}
	defer file.Close()
	fmt.Fprintf(file, "This is written to a file. Name: %s, Age: %d\n", name, age)
	fmt.Println("Data written to file.")
}

三、輸入格式化詳解

3.1 常用輸入函數(shù)

Go語言中,fmt 包提供了以下常用輸入函數(shù):

  • fmt.Scan(a ...interface{}):從標(biāo)準(zhǔn)輸入讀取數(shù)據(jù),按空格分隔。
  • fmt.Scanln(a ...interface{}):類似 Scan,但讀取到換行符時(shí)停止。
  • fmt.Scanf(format string, a ...interface{}):按格式化字符串讀取輸入。

3.2 案例

package main
import (
	"bufio"
	"fmt"
	"os"
	"strings"
)
func main() {
	// 使用 fmt.Scan 讀取輸入
	var name string
	var age int
	fmt.Print("Enter your name and age (separated by space): ")
	fmt.Scan(&name, &age)
	fmt.Printf("Name: %s, Age: %d\n", name, age)
	// 使用 fmt.Scanln 讀取輸入
	fmt.Print("Enter your name: ")
	fmt.Scanln(&name)
	fmt.Printf("Name: %s\n", name)
	// 使用 fmt.Scanf 讀取格式化輸入
	fmt.Print("Enter your name and age (format: Name Age): ")
	fmt.Scanf("%s %d", &name, &age)
	fmt.Printf("Name: %s, Age: %d\n", name, age)
	// 使用 bufio 讀取整行輸入
	reader := bufio.NewReader(os.Stdin)
	fmt.Print("Enter a sentence: ")
	sentence, _ := reader.ReadString('\n')
	sentence = strings.TrimSpace(sentence)
	fmt.Printf("You entered: %s\n", sentence)
}

代碼說明

  1. 輸出部分
    • PrintPrintln 用于簡單輸出,后者會(huì)自動(dòng)換行。
    • Printf 支持格式化動(dòng)詞,可以靈活控制輸出格式。
    • Sprintf 返回格式化后的字符串,不直接打印。
    • Fprintf 將格式化內(nèi)容寫入 io.Writer,如文件。
  2. 輸入部分
    • ScanScanln 用于讀取標(biāo)準(zhǔn)輸入,按空格或換行符分隔。
    • Scanf 支持格式化輸入,適用于特定格式的數(shù)據(jù)讀取。
    • bufio.NewReader 提供更高效的緩沖讀取功能,適合讀取整行輸入。

四、Go語言bufio詳解

bufio 是 “buffered I/O” 的縮寫,它通過在 I/O 操作中引入緩沖區(qū)來提升性能。這個(gè)包包裝了 io.Readerio.Writer 對象,創(chuàng)建了新的、帶緩沖的 ReaderWriter 實(shí)例,提供了額外的功能。

4.1 為什么需要bufio?(核心思想)

想象一下沒有緩沖區(qū)的 I/O 操作,就像用一個(gè)非常小的勺子(比如一次只能裝一個(gè)字節(jié))從一個(gè)大水桶(文件或網(wǎng)絡(luò)連接)里取水。每次取水都需要一個(gè)完整的“伸手-舀水-收回”的動(dòng)作,這個(gè)過程的開銷很大。
bufio 的作用就是引入一個(gè)“水杯”(緩沖區(qū))?,F(xiàn)在你的操作變成了:

  1. 用勺子從水桶里快速舀滿一杯水(一次性讀取一大塊數(shù)據(jù)到緩沖區(qū))。
  2. 需要用水時(shí),直接從水杯里倒(從緩沖區(qū)讀取數(shù)據(jù)給程序)。
    這個(gè)過程大大減少了“伸手-舀水-收回”的次數(shù),從而顯著提高了 I/O 效率,尤其是在處理大量小數(shù)據(jù)塊或網(wǎng)絡(luò)通信時(shí)。

核心優(yōu)勢:

  • 減少系統(tǒng)調(diào)用:將多次小的讀/寫操作合并為少數(shù)幾次大的操作,減少了昂貴的系統(tǒng)調(diào)用次數(shù)。
  • 提供高級功能:除了性能提升,bufio 還提供了許多便捷的方法,如按行讀取、按單詞讀取等。

4.2bufio.Reader:帶緩沖的讀取器

bufio.Reader 是一個(gè)結(jié)構(gòu)體,它包裝了一個(gè) io.Reader 接口。

1、創(chuàng)建 bufio.Reader:使用 bufio.NewReader 函數(shù)創(chuàng)建

func NewReader(rd io.Reader) *Reader

示例: 從標(biāo)準(zhǔn)輸入創(chuàng)建一個(gè)緩沖讀取器。

package main
import (
	"bufio"
	"fmt"
	"os"
)
func main() {
	// os.Stdin 實(shí)現(xiàn)了 io.Reader 接口
	reader := bufio.NewReader(os.Stdin)
	fmt.Printf("創(chuàng)建了一個(gè)緩沖區(qū)大小為 %d 字節(jié)的 Reader\n", reader.Size())
}

2、核心方法bufio.Reader 提供了一系列強(qiáng)大的讀取方法。

a) ReadString(delim byte) - 按分隔符讀取
這是最常用的方法之一。它會(huì)讀取數(shù)據(jù),直到遇到指定的分隔符 delim,然后返回包含分隔符在內(nèi)的字符串。

func (b *Reader) ReadString(delim byte) (string, error)

示例: 逐行讀取用戶輸入,直到用戶輸入 “exit”。

package main
import (
	"bufio"
	"fmt"
	"os"
	"strings"
)
func main() {
	reader := bufio.NewReader(os.Stdin)
	fmt.Println("請輸入內(nèi)容(輸入 'exit' 退出):")
	for {
		fmt.Print("> ")
		// 讀取直到遇到換行符 '\n'
		input, err := reader.ReadString('\n')
		if err != nil {
			fmt.Println("讀取錯(cuò)誤:", err)
			return
		}
		// 去除字符串兩端的空白字符(包括換行符)
		input = strings.TrimSpace(input)
		if input == "exit" {
			fmt.Println("程序退出。")
			break
		}
		fmt.Println("你輸入了:", input)
	}
}

b) ReadBytes(delim byte) - 按分隔符讀取字節(jié)切片
ReadString 類似,但返回的是 []byte 類型,在處理二進(jìn)制數(shù)據(jù)或需要更高性能時(shí)非常有用。

func (b *Reader) ReadBytes(delim byte) ([]byte, error)

c) ReadLine() - 讀取一行(不包含行尾符)
這是一個(gè)底層方法,它會(huì)讀取一行,但不包含行尾的 \r\n。它返回三個(gè)值:line (內(nèi)容), isPrefix (是否過長), err (錯(cuò)誤)。通常我們更常用 ReadString('\n'),因?yàn)樗唵沃庇^。

d) ReadSlice(delim byte) - 讀取到分隔符的切片

這個(gè)方法返回的是對緩沖區(qū)內(nèi)部數(shù)據(jù)的引用,而不是拷貝。這意味著下一次讀取操作可能會(huì)覆蓋這次返回的數(shù)據(jù)。它性能更高,但使用起來需要更小心。

e) Peek(n int) - 預(yù)覽數(shù)據(jù)
Peek 返回緩沖區(qū)接下來的 n 個(gè)字節(jié),但不會(huì)移動(dòng)讀取指針。也就是說,下次調(diào)用 Read 或其他讀取方法時(shí),仍然會(huì)從這次 Peek 的位置開始讀。非常適合用于“偷看”一下接下來的內(nèi)容是什么。

func (b *Reader) Peek(n int) ([]byte, error)

f) Read(p []byte) - 實(shí)現(xiàn) io.Reader 接口
bufio.Reader 本身也實(shí)現(xiàn)了 io.Reader 接口。當(dāng)你調(diào)用它的 Read 方法時(shí),它會(huì)嘗試從自己的緩沖區(qū)中填滿你提供的字節(jié)切片 p。如果緩沖區(qū)空了,它會(huì)從底層的 io.Reader 中讀取數(shù)據(jù)來填滿緩沖區(qū),然后再滿足你的請求。

4.3bufio.Writer:帶緩沖的寫入器

bufio.Writer 包裝了一個(gè) io.Writer 接口,將寫入操作先存入內(nèi)存緩沖區(qū),當(dāng)緩沖區(qū)滿了或被顯式刷新時(shí),才一次性寫入底層的 io.Writer。

創(chuàng)建 bufio.Writer:使用 bufio.NewWriter 函數(shù)創(chuàng)建:

func NewWriter(w io.Writer) *Writer

示例: 創(chuàng)建一個(gè)寫入標(biāo)準(zhǔn)輸出的緩沖寫入器。

package main
import (
	"bufio"
	"fmt"
	"os"
)
func main() {
	// os.Stdout 實(shí)現(xiàn)了 io.Writer 接口
	writer := bufio.NewWriter(os.Stdout)
	fmt.Printf("創(chuàng)建了一個(gè)緩沖區(qū)大小為 %d 字節(jié)的 Writer\n", writer.Size())
}

核心方法
a) Write(p []byte) - 寫入字節(jié)切片
這是最核心的寫入方法。它將數(shù)據(jù)寫入緩沖區(qū)。如果緩沖區(qū)有足夠空間,數(shù)據(jù)就暫存于此;如果空間不足,它會(huì)先將緩沖區(qū)的內(nèi)容刷到底層 Writer,然后再寫入新數(shù)據(jù)。
b) WriteString(s string) - 寫入字符串
WriteString 是一個(gè)便捷方法,內(nèi)部也是調(diào)用 Write
c) Flush() - 強(qiáng)制刷新
這是 bufio.Writer 最重要的方法。它會(huì)將緩沖區(qū)中所有(無論是否已滿)的數(shù)據(jù)都寫入到底層的 io.Writer 中。

為什么 Flush 如此重要?
因?yàn)槿绻徽{(diào)用 Flush(),當(dāng)程序結(jié)束時(shí),緩沖區(qū)里可能還有未寫入的數(shù)據(jù),這些數(shù)據(jù)就會(huì)丟失!

示例: 向文件寫入多行內(nèi)容。

package main
import (
	"bufio"
	"fmt"
	"log"
	"os"
)
func main() {
	// 1. 創(chuàng)建文件
	file, err := os.Create("output.txt")
	if err != nil {
		log.Fatal(err)
	}
	// 確保文件在函數(shù)結(jié)束時(shí)關(guān)閉
	defer file.Close()
	// 2. 創(chuàng)建緩沖寫入器
	writer := bufio.NewWriter(file)
	// 3. 寫入數(shù)據(jù)(此時(shí)數(shù)據(jù)在內(nèi)存緩沖區(qū)中)
	fmt.Fprintln(writer, "這是第一行。")
	fmt.Fprintln(writer, "這是第二行。")
	writer.WriteString("這是第三行,使用 WriteString。\n")
	// 4. **必須刷新緩沖區(qū),將數(shù)據(jù)寫入文件**
	err = writer.Flush()
	if err != nil {
		log.Fatal("刷新緩沖區(qū)失敗:", err)
	}
	fmt.Println("數(shù)據(jù)已成功寫入 output.txt")
}

在這個(gè)例子中,如果注釋掉 writer.Flush()output.txt 文件將是空的。

4.4bufio.Scanner:更高級的讀取工具

從 Go 1.1 開始,bufio 包引入了 Scanner 類型,它提供了一個(gè)更簡單、更健壯的方式來讀取數(shù)據(jù),特別是按“token”(標(biāo)記)分割數(shù)據(jù)。核心思想:
Scanner 的核心是 SplitFunc 類型的函數(shù),它定義了如何將輸入流分割成一個(gè)個(gè)標(biāo)記。默認(rèn)的分割函數(shù)是 ScanLines,即按行分割。

使用步驟

  1. 創(chuàng)建 Scanner: bufio.NewScanner(r io.Reader)
  2. (可選)設(shè)置分割函數(shù): scanner.Split(customSplitFunc)
  3. 循環(huán)掃描: 使用 scanner.Scan() 作為循環(huán)條件,它會(huì)嘗試讀取下一個(gè)標(biāo)記。
  4. 獲取標(biāo)記: 在循環(huán)體內(nèi),使用 scanner.Text() (返回 string) 或 scanner.Bytes() (返回 []byte) 獲取當(dāng)前標(biāo)記的內(nèi)容。
  5. 檢查錯(cuò)誤: 循環(huán)結(jié)束后,使用 scanner.Err() 檢查是否發(fā)生了錯(cuò)誤。

案例1:逐行讀取文件
使用 Scanner 逐行讀取文件比 Reader.ReadString 更簡潔,且能更好地處理行尾符。

package main
import (
	"bufio"
	"fmt"
	"log"
	"os"
	"strings"
)
func main() {
	// 1. 打開文件
	file, err := os.Open("my_file.txt")
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()
	// 2. 創(chuàng)建 Scanner
	scanner := bufio.NewScanner(file)
	lineCount := 0
	wordCount := 0
	// 3. 循環(huán)掃描
	for scanner.Scan() {
		line := scanner.Text()
		lineCount++
		// 簡單地按空格分割來計(jì)算單詞數(shù)
		words := strings.Fields(line)
		wordCount += len(words)
		fmt.Printf("行 %d: %s\n", lineCount, line)
	}
	// 4. 檢查錯(cuò)誤
	if err := scanner.Err(); err != nil {
		log.Fatal("掃描時(shí)出錯(cuò):", err)
	}
	fmt.Printf("\n掃描完成。共 %d 行,%d 個(gè)單詞。\n", lineCount, wordCount)
}

案例2:自定義分割函數(shù)
Scanner 的強(qiáng)大之處在于可以自定義分割邏輯。例如,我們可以按單詞讀取。
示例: 使用 ScanWords 分割函數(shù)按單詞讀取。

// ... (前面的代碼相同)
scanner := bufio.NewScanner(strings.NewReader("Hello world, this is a test."))
// 設(shè)置分割函數(shù)為按單詞分割
scanner.Split(bufio.ScanWords)
for scanner.Scan() {
	fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
    // ...
}

輸出:

Hello
world,
this
is
a
test.

4.5 使用對比

類型適用場景優(yōu)點(diǎn)注意事項(xiàng)
bufio.Reader需要精細(xì)控制讀取過程,如讀取固定字節(jié)數(shù)、預(yù)覽數(shù)據(jù)、讀取到特定分隔符。功能強(qiáng)大,控制力強(qiáng),性能高。API 相對底層,使用時(shí)需注意錯(cuò)誤處理。
bufio.Writer需要頻繁進(jìn)行小塊寫入,以減少系統(tǒng)調(diào)用,提高性能。顯著提升寫入性能。必須記得調(diào)用 Flush(),否則數(shù)據(jù)可能丟失。
bufio.Scanner需要方便地按行、按單詞等“標(biāo)記”來處理文本流。API 簡潔易用,代碼可讀性高,錯(cuò)誤處理方便。功能相對固定,不如 Reader 靈活。不適合讀取二進(jìn)制流。

Go語言的輸入與輸出格式化功能非常強(qiáng)大,通過 fmt 包和 bufio 包,可以滿足各種輸入輸出需求。掌握這些函數(shù)和格式化動(dòng)詞,有助于編寫清晰、易讀的 Go 程序。

到此這篇關(guān)于Go基礎(chǔ):輸入與輸出格式化詳解的文章就介紹到這了,更多相關(guān)Go輸入與輸出格式化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 簡單高效!Go語言封裝二級認(rèn)證功能實(shí)現(xiàn)

    簡單高效!Go語言封裝二級認(rèn)證功能實(shí)現(xiàn)

    本文將介紹如何使用Go語言封裝二級認(rèn)證功能,實(shí)現(xiàn)簡單高效的用戶認(rèn)證流程,二級認(rèn)證是一種安全措施,要求用戶在登錄后進(jìn)行額外的身份驗(yàn)證,以提高賬戶安全性,
    2023-10-10
  • 一文帶你掌握Golang的反射基礎(chǔ)

    一文帶你掌握Golang的反射基礎(chǔ)

    go的反射是由其標(biāo)準(zhǔn)庫中的reflect包實(shí)現(xiàn),該reflect包實(shí)現(xiàn)了在運(yùn)行時(shí)進(jìn)行反射的能力,本篇主要介紹了reflect的常用的幾個(gè)方法,希望對大家有所幫助
    2023-02-02
  • Golang Type關(guān)鍵字的使用

    Golang Type關(guān)鍵字的使用

    Type關(guān)鍵字在Go語言中作用很重要,比如定義結(jié)構(gòu)體,接口,還可以自定義類型,定義類型別名等,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-11-11
  • 深入解析Go語言編程中的遞歸使用

    深入解析Go語言編程中的遞歸使用

    這篇文章主要介紹了Go語言編程中的遞歸使用,是Go語言入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-11-11
  • Go?連接?MySQL之?MySQL?預(yù)處理詳解

    Go?連接?MySQL之?MySQL?預(yù)處理詳解

    Go語言提供了豐富的庫和工具,可以方便地連接MySQL數(shù)據(jù)庫。MySQL預(yù)處理是一種提高數(shù)據(jù)庫操作效率和安全性的技術(shù)。Go語言中的第三方庫提供了MySQL預(yù)處理的支持,通過使用預(yù)處理語句,可以避免SQL注入攻擊,并且可以提高數(shù)據(jù)庫操作的效率。
    2023-06-06
  • Go使用Pipeline實(shí)現(xiàn)一個(gè)簡潔而高效的數(shù)據(jù)處理流水線

    Go使用Pipeline實(shí)現(xiàn)一個(gè)簡潔而高效的數(shù)據(jù)處理流水線

    在并發(fā)編程中,流水線Pipeline是一種常見的設(shè)計(jì)模式,它將一個(gè)復(fù)雜任務(wù)拆解為多個(gè)獨(dú)立步驟,由多個(gè)協(xié)程并行處理并通過通道傳遞數(shù)據(jù),Go語言天生支持這種模型,能顯著提高數(shù)據(jù)處理的性能和可讀性,本文將給大家介紹如何使用Go實(shí)現(xiàn)一個(gè)簡潔而高效的數(shù)據(jù)處理流水線
    2025-08-08
  • Golang-如何判斷一個(gè)?interface{}?的值是否為?nil

    Golang-如何判斷一個(gè)?interface{}?的值是否為?nil

    interface?的內(nèi)部實(shí)現(xiàn)包含了兩個(gè)字段,一個(gè)是?type,一個(gè)是?data,這篇文章主要介紹了Golang-如何判斷一個(gè)interface{}的值是否為nil,需要的朋友可以參考下
    2023-05-05
  • 使用Go語言自制簡單易用的Web框架

    使用Go語言自制簡單易用的Web框架

    這篇文章主要為大家詳細(xì)介紹了如何使用Go語言實(shí)現(xiàn)自制簡單易用的Web框架,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • Golang 標(biāo)準(zhǔn)庫 tips之waitgroup詳解

    Golang 標(biāo)準(zhǔn)庫 tips之waitgroup詳解

    本篇文章給大家介紹Golang 標(biāo)準(zhǔn)庫 tips之waitgroup的相關(guān)知識,包括使用 channel 實(shí)現(xiàn) WaitGroup 的功能介紹,感興趣的朋友跟隨小編一起看看吧
    2021-07-07
  • 簡單易用的Go逗號comma ok模式使用詳解

    簡單易用的Go逗號comma ok模式使用詳解

    這篇文章主要為大家介紹了簡單易用的Go逗號comma ok模式使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11

最新評論

茌平县| 荣成市| 资兴市| 镇赉县| 屯昌县| 台中县| 工布江达县| 浦北县| 沿河| 武平县| 长白| 巴彦淖尔市| 台中县| 屏山县| 榆中县| 咸阳市| 盐津县| 安塞县| 垣曲县| 桦甸市| 包头市| 和林格尔县| 保亭| 容城县| 阿勒泰市| 江门市| 新泰市| 新宾| 永福县| 鞍山市| 秦皇岛市| 楚雄市| 锦屏县| 封开县| 青铜峡市| 乌兰县| 潜江市| 仪陇县| 长春市| 深水埗区| 佛山市|