Bài 1: Ba gia tộc In ấn (Print, Fprint, Sprint) trong package fmt
Package fmt trong Go thiết kế các hàm xuất dữ liệu theo một ma trận cực kỳ logic. Chúng được chia thành 3 "gia tộc" dựa trên đích đến của dữ liệu (Print, Sprint, Fprint), và mỗi gia tộc lại có 3 biến thể dựa trên cách định dạng (thuần, ln, f).
Hiểu rõ cấu trúc này giúp bạn không bao giờ phải bối rối khi tìm cách nối chuỗi hay xuất dữ liệu ra file.
1. Gia tộc Print: Xuất ra màn hình (Terminal)
Đây là nhóm hàm quen thuộc nhất, mặc định đẩy dữ liệu trực tiếp ra luồng tiêu chuẩn của hệ điều hành là os.Stdout (màn hình console).
fmt.Print: In các giá trị sát vào nhau, không tự động xuống dòng. Chỉ tự động chèn khoảng trắng nếu cả hai toán hạng đều không phải là chuỗi.fmt.Println: (Print Line) Luôn chèn khoảng trắng giữa các giá trị và tự động thêm một ký tự xuống dòng\nở cuối cùng.fmt.Printf: (Print Format) Không tự động xuống dòng, nhưng cho phép bạn chèn các biến vào một chuỗi mẫu (template) thông qua các ký tự%.
Ví dụ minh họa:
package main
import "fmt"
func main() {
name := "Golang"
version := 1.22
// Print: In dính liền
fmt.Print("Ngôn ngữ: ", name)
fmt.Print(" Phiên bản: ", version, "\n")
// Kết quả: Ngôn ngữ: Golang Phiên bản: 1.22
// Println: Tự động có khoảng trắng và xuống dòng
fmt.Println("Ngôn ngữ:", name, "Phiên bản:", version)
// Kết quả: Ngôn ngữ: Golang Phiên bản: 1.22
// Printf: Định dạng với placeholder
fmt.Printf("Ngôn ngữ: %s - Phiên bản: %.2f\n", name, version)
// Kết quả: Ngôn ngữ: Golang - Phiên bản: 1.22
}
2. Gia tộc Sprint: Gom thành biến String
Chữ S ở đây đại diện cho String. Nhóm hàm này có cách hoạt động y hệt nhóm Print, nhưng không in ra bất cứ đâu cả. Thay vào đó, nó gom tất cả lại và trả về kết quả dưới dạng một biến kiểu string.
Gia tộc này cực kỳ hữu ích khi bạn cần lắp ráp một chuỗi phức tạp để làm câu query SQL, tạo nội dung email, hoặc gán vào một trường của struct JSON trước khi gửi đi.
Ví dụ minh họa:
package main
import "fmt"
func main() {
cpu := 8
ram := 16
// Sprintf trả về một chuỗi
serverSpec := fmt.Sprintf("Server cấu hình: %d Cores, %d GB RAM", cpu, ram)
// Bạn có thể dùng chuỗi này cho các logic khác
if ram >= 16 {
serverSpec += " (Đủ tiêu chuẩn chạy Docker)"
}
fmt.Println(serverSpec)
}
3. Gia tộc Fprint: Xuất ra luồng I/O (File, Network)
Chữ F ở đây thường được hiểu là File hoặc Format to writer. Đích đến của nhóm hàm này không bị giới hạn ở màn hình hay biến bộ nhớ. Tham số đầu tiên của chúng luôn yêu cầu một đối tượng thỏa mãn interface io.Writer.
Nhờ cơ chế interface này, bạn có thể dùng Fprint để đẩy text thẳng vào một File trên ổ cứng, hoặc đẩy qua mạng thông qua http.ResponseWriter để trả về cho trình duyệt.
Ví dụ minh họa:
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
// 1. Dùng Fprintln để ghi vào File
file, _ := os.Create("report.txt")
defer file.Close()
// Đẩy chuỗi vào file thay vì in ra màn hình
fmt.Fprintln(file, "Báo cáo doanh thu tháng 9")
// 2. Dùng Fprintf để trả HTTP Response
http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
// w chính là một io.Writer
name := r.URL.Query().Get("name")
fmt.Fprintf(w, "Xin chào, %s! Chào mừng đến với API.", name)
})
// http.ListenAndServe(":8080", nil)
}
📊 Bảng Tổng Kết Ma Trận fmt
| Đích đến | Không định dạng | Cú pháp Format (%) |
Có tự xuống dòng |
|---|---|---|---|
Màn hình (os.Stdout) |
Print() |
Printf() |
Println() |
| Biến string | Sprint() |
Sprintf() |
Sprintln() |
Luồng io.Writer |
Fprint() |
Fprintf() |
Fprintln() |
All rights reserved