Package và Import

Package là gì?

Package là đơn vị tổ chức code trong Go. Mọi file Go bắt đầu bằng khai báo package:

package main     // package đặc biệt: tạo file thực thi
package mathutil  // package thư viện: được import bởi package khác

Exported vs Unexported

Go dùng viết hoa/thường để kiểm soát visibility — không cần public/private:

package mathutil

// EXPORTED — có thể dùng từ package khác
func Add(a, b int) int { return a + b }
const Pi = 3.14159
type Circle struct{ Radius float64 }

// UNEXPORTED — chỉ dùng trong package này
func helper() {}
var cache = map[string]int{}
type internalState struct{ ... }

Import

import "fmt"       // single import

import (           // grouped import (khuyến khích)
    "fmt"
    "math"
    "os"
    "strings"
)

// Alias
import f "fmt"
f.Println("hello")

// Blank import: chỉ chạy init(), không dùng package
import _ "image/png"  // đăng ký PNG decoder

init() — Hàm khởi tạo đặc biệt

package mypackage

var db *sql.DB

func init() {
    // Chạy tự động trước main()
    // Không có tham số, không có giá trị trả về
    db = connectToDB()
}

// Có thể có nhiều init() trong một file
// Thứ tự: package deps → init() → main()

Module System — go.mod

# Khởi tạo module mới
go mod init github.com/ban/tenproject

# Tải dependency
go get github.com/gin-gonic/gin@v1.9.1

# Dọn dẹp dependencies thừa
go mod tidy
// go.mod
module github.com/ban/tenproject

go 1.23

require (
    github.com/go-chi/chi/v5 v5.0.11
    golang.org/x/crypto v0.21.0
)

Thư viện chuẩn hay dùng

Package Dùng để
fmt In, format string (Printf, Sprintf, Errorf)
os File I/O, environment, args
io Interface Reader/Writer
strings Thao tác chuỗi
strconv Chuyển đổi kiểu (Atoi, Itoa, ParseFloat)
math Toán học (Sqrt, Abs, Pi)
sort Sắp xếp
time Thời gian, duration
net/http HTTP server/client
encoding/json JSON encode/decode
sync Mutex, WaitGroup
context Cancellation, deadline

Quy ước đặt tên trong Go

// Package: chữ thường, ngắn, không dấu gạch
package http    // ✓
package myUtil  // ✗

// Biến/hàm: camelCase
userName := "An"     // ✓
user_name := "An"    // ✗ (không dùng snake_case)

// Hằng số: cũng camelCase (KHÔNG dùng ALL_CAPS như C)
const maxRetry = 3   // ✓ (unexported)
const MaxRetry = 3   // ✓ (exported)
const MAX_RETRY = 3  // ✗

// Interface: thường kết thúc bằng -er
type Reader interface { Read(p []byte) (n int, err error) }
type Writer interface { Write(p []byte) (n int, err error) }
example.go
package main

import (
	"encoding/json"
	"fmt"
	"math"
	"os"
	"sort"
	"strconv"
	"strings"
	"time"
)

func main() {
	// strings
	s := "  Xin chào, Go!  "
	fmt.Println(strings.TrimSpace(s))
	fmt.Println(strings.ToUpper(s))
	fmt.Println(strings.Replace(s, "Go", "Golang", 1))
	parts := strings.Split("a,b,c,d", ",")
	fmt.Println(parts, len(parts))

	// strconv
	n, _ := strconv.Atoi("42")
	fmt.Println(n + 8)
	fmt.Println(strconv.FormatFloat(math.Pi, 'f', 4, 64))

	// sort
	nums := []int{5, 2, 8, 1, 9}
	sort.Ints(nums)
	fmt.Println(nums)

	words := []string{"chuối", "táo", "xoài", "ổi"}
	sort.Strings(words)
	fmt.Println(words)

	// time
	now := time.Now()
	fmt.Println(now.Format("02/01/2006 15:04:05"))

	// json
	type Point struct {
		X, Y int
	}
	p := Point{3, 4}
	data, _ := json.Marshal(p)
	fmt.Println(string(data))

	// os - args
	fmt.Println("Chương trình:", os.Args[0])
}