👨‍💻簡介

要印出Hello World,就會碰到這個Package -> fmt,今天來簡單整理一下fmt的作用、格式化的控制與常見用法。

主要功能

fmt 套件的主要功能是處理格式化的輸出和輸入,包括資料格式處理、字串解析和數值轉換等功能。通常用來記錄訊息、檔案處理等等。fmt 套件中的函數可以主要分為兩大類:PrintScan

導入Package

import "fmt"
  • fmt.Print:將資料印到終端機。
  • fmt.Println:將資料印到終端機,並換行。
  • fmt.Printf:根據格式化參數將資料印到終端機。
  • fmt.Sprintf:格式化成字串,通常用在需要以字串形式處理格式化時會用到
  • fmt.Fprintf:格式化到文件,通常用來寫檔會用到

PrintPrintf相比,差在不能印格式化輸出
PrintPrintln相比,差在ln多了一個換行

package main

import (
	"fmt"
	"os"
)

func main() {
    name := "Alan"
    age := 30
    fmt.Print("Name: ", name, " Age: ", age)      // 沒有換行
    fmt.Println("Name:", name, "Age:", age)       // 有換行
    fmt.Printf("Name: %s Age: %d\n", name, age)   // 格式化印出

	formatted := fmt.Sprintf("Name: %s, Age: %d", name, age)
	fmt.Println(formatted)                        // 輸出格式化後的字串


	file, _ := os.Create("output.txt") 
	defer file.Close()

	fmt.Fprintf(file, "Name: %s, Age: %d", name, age) // 將格式化後的內容寫入檔案
}

Scan 函數系列

  • fmt.Scan:讀取一個或多個空格分隔的值。
  • fmt.Scanf:格式化讀取。
  • fmt.Scanln:讀取一行內容。
  • fmt.Fscanf:從文件中格式化讀取
package main

import (
    "fmt"
    "os"
)

func main() {
    // 使用 fmt.Scan 讀取一個或多個空格分隔的值
    var name string
    var age int
    fmt.Print("Enter your name and age (space-separated): ")
    fmt.Scan(&name, &age)
    fmt.Printf("Name: %s Age: %d\n", name, age)

    // 使用 fmt.Scanf 進行格式化讀取
    var height float64
    fmt.Print("Enter your height in meters: ")
    fmt.Scanf("%f", &height)
    fmt.Printf("Height: %.2f meters\n", height)

    // 使用 fmt.Scanln 讀取一行內容
    var city string
    var country string
    fmt.Print("Enter your city and country: ")
    fmt.Scanln(&city, &country)
    fmt.Printf("City: %s Country: %s\n", city, country)

    // 使用 fmt.Fscanf 從文件中格式化讀取
    file, _ := os.Open("input.txt")
    defer file.Close()

    var code int
    var message string
    fmt.Fscanf(file, "%d %s", &code, &message)
    fmt.Printf("Code: %d Message: %s\n", code, message)
}

格式化控制

常見的格式化參數

在Go的fmtPackage中,常見的格式化參數用來指定印出的格式。這邊列舉一些常見的格式化參數:

  • %s:string (字串)
  • %c:char (字元)
  • %d:digit (10進位的數字)
  • %f:float (浮點數)
  • %t:bool (布林值)
  • %v: value (值)
package main

import "fmt"

func main() {
    name := "Alan"
    age := 30
    firstChar := 'A'
    height := 5.8
    isStudent := true

    fmt.Printf("Name: %s\n", name)              // Name: Alan
    fmt.Printf("Age: %d\n", age)                // Age: 30
    fmt.Printf("First Char: %c\n", firstChar)   // First Char: A
    fmt.Printf("Height: %.2f\n", height)        // Height: 5.8
    fmt.Printf("Is Student: %t\n", isStudent)   // Is Student: true
}

%v還能夠顯示更詳細的資訊

  • %+v: value (以詳細格式輸出,印出 struct 時,會多欄位名稱)
  • %#v: value (以Go語言語法輸出,印出 struct 時,會多 struct 名稱與欄位名稱)
type Person struct {
    FirstName string
    LastName  string
    Age       int
}

func main() {
    person := Person{
        FirstName: "Alan",
        LastName:  "Wang",
        Age:       30,
    }
    fmt.Printf("%+v\n", person)      // {FirstName:John LastName:Doe Age:30}
    fmt.Printf("%#v\n", person)      // main.Person{FirstName:"John", LastName:"Doe", Age:30}
}

寬度和精度

在格式化字符串中,我們可以使用寬度(Width)和精度(Precision)來調整印出的長度和小數點位數。例如,%8.2f表示印出浮點數佔8個字符的寬度,並保留2位小數。

package main

import "fmt"

func main() {
	num := 123.456789
	fmt.Printf("Default: %f\n", num)
	fmt.Printf("Width 16: %16f\n", num)
	fmt.Printf("Width 8, Precision 2: %8.2f\n", num)
}

格式化選項

格式化選項可以讓我們設定對齊方式、填充字符等。例如,%-8s代表向左對齊,並在不足8個字符時使用空格進行填充。

package main

import "fmt"

func main() {
    name := "Alan"
    fmt.Printf("Name: %-8s|\n", name)
    fmt.Printf("Name: %8s|\n", name)
    fmt.Printf("Name: %.8s|\n", name)
}

常見用法

字串格式化

package main

import "fmt"

func main() {
    name := "Alan"
    greeting := fmt.Sprintf("Hello, %s!", name)
    fmt.Println(greeting)
}

數值格式化

package main

import "fmt"

func main() {
    num := 42
    fmt.Printf("Decimal: %d\n", num)
    fmt.Printf("Hexadecimal: %x\n", num)
    fmt.Printf("Binary: %b\n", num)
}

時間格式化

package main

import (
    "fmt"
    "time"
)

func main() {
    now := time.Now()
    fmt.Printf("Current time: %s\n", now.Format("2006-01-02 15:04:05"))
}

JSON 讀取和印出

package main

import (
    "encoding/json"
    "fmt"
)

type Person struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

func main() {
    // 將Struct轉換為JSON
    person := Person{Name: "Alan", Age: 30}
    jsonBytes, _ := json.Marshal(person)
    fmt.Println(string(jsonBytes))

    // 從JSON解析Struct
    jsonStr := `{"name":"Bob","age":25}`
    var anotherPerson Person
    json.Unmarshal([]byte(jsonStr), &anotherPerson)
    fmt.Printf("Name: %s Age: %d\n", anotherPerson.Name, anotherPerson.Age)
}

📚Reference