Ecosystem thực chiến
F1. Go Modules
# Khởi tạo project
go mod init github.com/user/project
# Thêm thư viện
go get github.com/gin-gonic/gin
# Dọn dẹp dependency thừa
go mod tidy
# Xem cây phụ thuộc
go mod graph
File go.mod
module github.com/user/project
go 1.22
require (
github.com/gin-gonic/gin v1.9.1
golang.org/x/sync v0.5.0
)
go.sum = checksum để đảm bảo build có thể tái tạo (reproducible).
F2. Testing
File math_test.go (đặt cạnh math.go)
package math
import "testing"
func TestAdd(t *testing.T) {
got := Add(2, 3)
if got != 5 {
t.Errorf("Add(2,3) = %d; muốn 5", got)
}
}
Table-driven test (chuẩn Go)
func TestAdd(t *testing.T) {
tests := []struct{
name string
a, b, want int
}{
{"cộng dương", 2, 3, 5},
{"cộng âm", -1, -2, -3},
{"với 0", 0, 5, 5},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := Add(tt.a, tt.b); got != tt.want {
t.Errorf("got %d, want %d", got, tt.want)
}
})
}
}
Benchmark
func BenchmarkAdd(b *testing.B) {
for i := 0; i < b.N; i++ {
Add(2, 3)
}
}
Chạy: go test -bench=.
Coverage
go test -cover
go test -coverprofile=cover.out && go tool cover -html=cover.out
F3. JSON
Marshal — Struct → JSON
type User struct {
Name string `json:"name"`
Age int `json:"age,omitempty"`
}
u := User{Name: "Alice", Age: 30}
b, _ := json.Marshal(u)
fmt.Println(string(b)) // {"name":"Alice","age":30}
Unmarshal — JSON → Struct
data := []byte(`{"name":"Bob","age":25}`)
var u User
json.Unmarshal(data, &u) // ⚠️ nhớ truyền con trỏ
Field ẩn/tuỳ chọn
`json:"-"` // Bỏ qua
`json:"name,omitempty"` // Bỏ nếu zero value
`json:"name,string"` // Ép sang string
F4. HTTP server & client
Server siêu ngắn
func main() {
http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Xin chào,", r.URL.Query().Get("name"))
})
http.ListenAndServe(":8080", nil)
}
Client
resp, err := http.Get("https://api.example.com/users")
if err != nil { log.Fatal(err) }
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
JSON POST
data, _ := json.Marshal(map[string]string{"key": "value"})
resp, _ := http.Post("https://api...", "application/json", bytes.NewBuffer(data))
F5. File I/O
Đọc toàn bộ file
data, err := os.ReadFile("config.yaml")
Ghi toàn bộ file
os.WriteFile("out.txt", []byte("hello"), 0644)
Đọc từng dòng (file lớn)
f, _ := os.Open("big.log")
defer f.Close()
scanner := bufio.NewScanner(f)
for scanner.Scan() {
fmt.Println(scanner.Text())
}