0

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

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí