☰ Mục lục series
Tài liệu Go tiếng Việt
  1. Bắt đầu (Getting started)
    1. Tổng quan
    2. Tải về và cài đặt
    3. Bắt đầu với Go
    4. Quản lý các bản cài đặt Go
    5. Plugin trình soạn thảo và IDE
  2. Dạo quanh Go (A Tour of Go)
    1. Chào mừng
    2. Package, biến và hàm
    3. Điều khiển luồng
    4. Struct, slice và map
    5. Method và interface
    6. Generics
    7. Xử lý đồng thời
  3. Hướng dẫn (Tutorials)
    1. Danh sách hướng dẫn
    2. Tạo một Go module
    3. Gọi mã của bạn từ một module khác
    4. Trả về và xử lý lỗi
    5. Trả về lời chào ngẫu nhiên
    6. Trả về lời chào cho nhiều người
    7. Thêm một test
    8. Biên dịch và cài đặt ứng dụng
    9. Kết luận
    10. Bắt đầu với workspace nhiều module
    11. Phát triển RESTful API với Go và Gin
    12. Truy cập cơ sở dữ liệu quan hệ
    13. Bắt đầu với generics
    14. Bắt đầu với fuzzing
    15. Làm việc với JSON
    16. Tìm và sửa các dependency có lỗ hổng với govulncheck
    17. Tìm và khắc phục phụ thuộc có lỗ hổng với VS Code Go
    18. Viết ứng dụng web
  4. Viết code Go
    1. Cách viết mã Go
    2. Effective Go
    3. Doc Comment trong Go
  5. Module
    1. Phát triển và publish module
    2. Quản lý phụ thuộc
    3. Tổ chức một module Go
    4. Quản lý mã nguồn của module
    5. Cách đánh số phiên bản module
    6. Quy trình phát hành và đánh phiên bản module
    7. Publish một module
    8. Phát triển một bản cập nhật major version
    9. Tham chiếu tệp go.mod
    10. Ngừng hỗ trợ 'go get' cho việc cài đặt tệp thực thi
  6. Cơ sở dữ liệu (Database)
    1. Truy cập cơ sở dữ liệu quan hệ
    2. Mở một handle cơ sở dữ liệu
    3. Thực thi câu lệnh SQL không trả về dữ liệu
    4. Truy vấn dữ liệu
    5. Dùng prepared statement
    6. Thực thi transaction
    7. Huỷ các thao tác đang chạy
    8. Quản lý kết nối
    9. Tránh rủi ro SQL injection
  7. Chẩn đoán và hiệu năng
    1. Chẩn đoán
    2. Hướng dẫn về Go Garbage Collector
    3. Tối ưu hoá dựa trên profile
    4. Data Race Detector
    5. Gỡ lỗi mã Go bằng GDB
    6. Hỗ trợ coverage profiling cho integration test
  8. Bảo mật (Security)
    1. Tổng quan bảo mật
    2. Thực hành tốt về bảo mật cho lập trình viên Go
    3. Quản lý lỗ hổng trong Go
    4. Cơ sở dữ liệu lỗ hổng của Go
    5. Quét lỗ hổng trong IDE
    6. Chính sách CNA của Go
    7. Go Fuzzing
    8. Chi tiết kỹ thuật của Go Fuzzing
    9. Chính sách bảo mật của Go
    10. Threat Model của Go
    11. Các quyết định về bảo mật của Go
    12. Tuân thủ FIPS 140-3
  9. Công cụ và toolchain
    1. Tài liệu về các lệnh
    2. Về lệnh go
    3. Go Toolchains
    4. Telemetry của Go
    5. Cài đặt Go từ mã nguồn
    6. Cài đặt và sử dụng gccgo
  10. Tham khảo
    1. Câu hỏi thường gặp (FAQ)
    2. Go 1 và tương lai của các chương trình Go
    3. Hướng dẫn chuyển đổi sang encoding/json/v2
    4. Hướng dẫn đóng góp
    5. Đóng góp cho frontend gccgo
  11. Phụ lục
    1. Bảng thuật ngữ
Công cụ và toolchain

Cài đặt Go từ mã nguồn

Bản dịch từ go.dev/doc/install/source

Chủ đề này mô tả cách build và chạy Go từ mã nguồn. Để cài đặt bằng installer, hãy xem Tải về và cài đặt.

Giới thiệu

Go là một dự án mã nguồn mở, được phát hành theo giấy phép kiểu BSD. Tài liệu này giải thích cách lấy mã nguồn về, biên dịch chúng trên chính máy của bạn và chạy chúng.

Phần lớn người dùng không cần làm việc này, và thay vào đó sẽ cài đặt từ các gói binary đã được biên dịch sẵn như mô tả trong Tải về và cài đặt, một quy trình đơn giản hơn nhiều. Tuy nhiên, nếu bạn muốn góp sức phát triển những gì nằm trong các gói biên dịch sẵn đó, hãy đọc tiếp.

Có hai toolchain compiler chính thức của Go. Tài liệu này tập trung vào compiler và các công cụ Go gc. Để biết cách làm việc với gccgo, một compiler truyền thống hơn dùng back end của GCC, hãy xem Thiết lập và sử dụng gccgo.

Các compiler của Go hỗ trợ những tập lệnh sau:

amd64, 386
Tập lệnh x86, 64-bit và 32-bit.
arm64, arm
Tập lệnh ARM, 64-bit (AArch64) và 32-bit.
loong64
Tập lệnh LoongArch 64-bit.
mips64, mips64le, mips, mipsle
Tập lệnh MIPS, big-endian và little-endian, 64-bit và 32-bit.
ppc64, ppc64le
Tập lệnh PowerPC 64-bit, big-endian và little-endian.
riscv64
Tập lệnh RISC-V 64-bit.
s390x
Kiến trúc IBM z/Architecture.
wasm
WebAssembly.

Các compiler có thể nhắm tới những hệ điều hành AIX, Android, DragonFly BSD, FreeBSD, Illumos, Linux, macOS/iOS (Darwin), NetBSD, OpenBSD, Plan 9, Solaris và Windows (dù không phải hệ điều hành nào cũng hỗ trợ mọi kiến trúc).

Danh sách các port được xem là “hạng nhất” có trên trang wiki first class ports.

Toàn bộ các tổ hợp được hỗ trợ được liệt kê trong phần trình bày về environment variable bên dưới.

Xem trang MinimumRequirements trên Go Wiki để biết yêu cầu hệ thống tổng quát.

Cài đặt binary của Go compiler để bootstrap

Toolchain của Go được viết bằng Go. Để build nó, bạn cần có sẵn một Go compiler. Các script thực hiện lần build đầu tiên của các công cụ sẽ tìm câu lệnh “go” trong $PATH, nên chỉ cần bạn đã cài Go trên hệ thống và cấu hình nó trong $PATH, là bạn đã sẵn sàng build Go từ mã nguồn. Hoặc nếu muốn, bạn có thể đặt $GOROOT_BOOTSTRAP trỏ tới thư mục gốc của một bản cài đặt Go dùng để build toolchain Go mới; $GOROOT_BOOTSTRAP/bin/go phải là câu lệnh go sẽ được dùng.

Phiên bản Go tối thiểu cần có phụ thuộc vào phiên bản Go đích:

  • Go <= 1.4: một toolchain C.
  • 1.5 <= Go <= 1.19: một compiler Go 1.4.
  • 1.20 <= Go <= 1.21: một compiler Go 1.17.
  • 1.22 <= Go <= 1.23: một compiler Go 1.20.
  • Về sau, phiên bản Go 1.N sẽ cần một compiler Go 1.M, trong đó M là N-2 làm tròn xuống tới số chẵn. Ví dụ: Go 1.24 và 1.25 cần Go 1.22.

Có bốn cách để có được một toolchain bootstrap:

  • Tải về một bản phát hành binary gần đây của Go.
  • Cross-compile một toolchain bằng một hệ thống đã có bản cài đặt Go hoạt động được.
  • Dùng gccgo.
  • Biên dịch một toolchain từ Go 1.4, bản phát hành Go cuối cùng có compiler viết bằng C.

Các cách này được trình bày chi tiết bên dưới.

Toolchain bootstrap từ bản phát hành binary

Để dùng một bản phát hành binary làm toolchain bootstrap, hãy xem trang tải về hoặc dùng bất kỳ bản phân phối Go đóng gói sẵn nào đáp ứng yêu cầu phiên bản tối thiểu.

Toolchain bootstrap từ mã nguồn cross-compile

Để cross-compile một toolchain bootstrap từ mã nguồn, việc này là cần thiết trên các hệ thống mà Go 1.4 không nhắm tới (ví dụ linux/ppc64le), hãy cài Go trên một hệ thống khác rồi chạy bootstrap.bash.

Khi chạy (chẳng hạn) như sau

$ GOOS=linux GOARCH=ppc64 ./bootstrap.bash

bootstrap.bash sẽ cross-compile một toolchain cho tổ hợp GOOS/GOARCH đó, để lại cây thư mục kết quả tại ../../go-${GOOS}-${GOARCH}-bootstrap. Cây thư mục đó có thể được sao chép sang một máy thuộc kiểu đích tương ứng và dùng làm GOROOT_BOOTSTRAP để bootstrap một bản build cục bộ.

Toolchain bootstrap dùng gccgo

Để dùng gccgo làm toolchain bootstrap, bạn cần thu xếp sao cho $GOROOT_BOOTSTRAP/bin/go là công cụ go đi kèm gccgo 5. Ví dụ trên Ubuntu Vivid:

$ sudo apt-get install gccgo-5
$ sudo update-alternatives --set go /usr/bin/go-5
$ GOROOT_BOOTSTRAP=/usr ./make.bash

Toolchain bootstrap từ mã nguồn C

Để build một toolchain bootstrap từ mã nguồn C, hãy dùng branch git release-branch.go1.4 hoặc go1.4-bootstrap-20171003.tar.gz, vốn chứa mã nguồn Go 1.4 cùng các bản vá tích luỹ để các công cụ vẫn chạy được trên những hệ điều hành mới hơn. (Go 1.4 là bản phân phối cuối cùng có toolchain viết bằng C.) Sau khi giải nén mã nguồn Go 1.4, hãy cd vào thư mục con src, đặt CGO_ENABLED=0 trong môi trường, rồi chạy make.bash (hoặc, trên Windows, make.bat).

Sau khi mã nguồn Go 1.4 đã được giải nén vào thư mục GOROOT_BOOTSTRAP của bạn, bạn phải giữ bản git clone này ở branch release-branch.go1.4. Cụ thể, đừng tìm cách dùng lại bản git clone này ở bước sau có tên “Lấy repository về”. Toolchain bootstrap go1.4 phải có khả năng duyệt đúng mã nguồn go1.4 mà nó giả định là đang nằm dưới thư mục gốc của repository này.

Lưu ý rằng Go 1.4 không chạy được trên mọi hệ thống mà các phiên bản Go sau này chạy được. Cụ thể, Go 1.4 không hỗ trợ các phiên bản macOS hiện nay. Trên những hệ thống như vậy, toolchain bootstrap phải được lấy bằng một trong các cách còn lại.

Cài đặt Git, nếu cần

Để thực hiện bước tiếp theo, bạn phải có Git. (Hãy kiểm tra xem bạn đã có câu lệnh git chưa trước khi đi tiếp.)

Nếu bạn chưa có một bản cài đặt Git hoạt động được, hãy làm theo hướng dẫn trên trang Git downloads.

(Tuỳ chọn) Cài đặt một C compiler

Để build một bản cài đặt Go có hỗ trợ cgo, thứ cho phép các chương trình Go import thư viện C, trước hết phải cài một C compiler như gcc hoặc clang. Hãy làm việc này bằng cách cài đặt theo cách chuẩn trên hệ thống của bạn.

Để build mà không có cgo, hãy đặt environment variable CGO_ENABLED=0 trước khi chạy all.bash hoặc make.bash.

Lấy repository về

Hãy chuyển vào thư mục nơi bạn định cài Go, và bảo đảm thư mục goroot chưa tồn tại. Sau đó clone repository rồi check out tag phát hành mới nhất hoặc branch phát hành (ví dụ go1.22.0, hoặc release-branch.go1.22):

$ git clone https://go.googlesource.com/go goroot
$ cd goroot
$ git checkout <tag>

Trong đó <tag> là chuỗi phiên bản của bản phát hành.

Go sẽ được cài vào thư mục nơi nó được check out. Ví dụ, nếu Go được check out trong $HOME/goroot, các tệp thực thi sẽ được cài trong $HOME/goroot/bin. Thư mục này có thể mang tên bất kỳ, nhưng lưu ý rằng nếu Go được check out trong $HOME/go, nó sẽ xung đột với vị trí mặc định của $GOPATH. Xem GOPATH bên dưới.

Nhắc lại: Nếu bạn đã chọn biên dịch cả các binary bootstrap từ mã nguồn (ở phần trước), thì đến đây bạn vẫn cần git clone lại một lần nữa (để check out <tag> mới nhất), bởi bạn phải giữ riêng repository go1.4 của mình.

(Tuỳ chọn) Chuyển sang branch master

Nếu bạn định sửa mã nguồn go, và đóng góp thay đổi của mình cho dự án, hãy chuyển repository của bạn khỏi tag phát hành, sang branch master (phát triển). Nếu không, hãy bỏ qua bước này.

$ git checkout master

Cài đặt Go

Để build bản phân phối Go, hãy chạy

$ cd src
$ ./make.bash

(Để build trên Windows, hãy dùng make.bat.)

Nếu mọi thứ suôn sẻ, quá trình sẽ kết thúc bằng đầu ra như sau:

---
Installed Go for linux/amd64 in /home/you/go.
Installed commands in /home/you/go/bin.
*** You need to add /home/you/go/bin to your $PATH. ***

trong đó chi tiết ở vài dòng cuối phản ánh hệ điều hành, kiến trúc và thư mục gốc được dùng trong quá trình cài đặt.

Để biết thêm về các cách điều khiển quá trình build, hãy xem phần trình bày về environment variable bên dưới. Bạn cũng có thể chạy all.bash (hoặc all.bat) để chạy các bài kiểm tra quan trọng của Go, việc này có thể mất nhiều thời gian hơn so với chỉ build Go.

Kiểm tra bản cài đặt của bạn

Hãy kiểm tra xem Go đã được cài đúng chưa bằng cách build một chương trình đơn giản.

Tạo một tệp tên hello.go và đặt chương trình sau vào đó:

package main

import "fmt"

func main() {
	fmt.Printf("hello, world\n")
}

Rồi chạy nó bằng công cụ go:

$ go run hello.go
hello, world

Nếu bạn thấy dòng chữ “hello, world” thì Go đã được cài đúng.

Thiết lập môi trường làm việc của bạn

Bạn gần xong rồi. Chỉ cần thiết lập thêm một chút nữa thôi.

Cách viết mã Go — Học cách thiết lập và sử dụng các công cụ của Go

Tài liệu Cách viết mã Go cung cấp các hướng dẫn thiết lập thiết yếu để sử dụng các công cụ của Go.

Cài đặt thêm công cụ

Mã nguồn của một số công cụ Go (bao gồm gopls) được giữ trong repository golang.org/x/tools. Để cài một trong các công cụ đó (ở đây là gopls):

$ go install golang.org/x/tools/gopls@latest

Tài nguyên cộng đồng

Các tài nguyên cộng đồng thường dùng được liệt kê trên trang trợ giúp có những người phát triển tích cực, họ có thể giúp bạn giải quyết vấn đề với bản cài đặt hoặc công việc phát triển của bạn. Với những ai muốn cập nhật thường xuyên, còn có một mailing list khác là golang-checkins, nơi nhận thông báo tóm tắt mỗi lần checkin vào repository của Go.

Có thể báo lỗi qua trình theo dõi issue của Go.

Theo kịp các bản phát hành

Các bản phát hành mới được thông báo trên mailing list golang-announce. Mỗi thông báo đều nhắc tới tag phát hành mới nhất, chẳng hạn go1.9.

Để cập nhật một cây thư mục đã có lên bản phát hành mới nhất, bạn có thể chạy:

$ cd go/src
$ git fetch
$ git checkout <tag>
$ ./all.bash

Trong đó <tag> là chuỗi phiên bản của bản phát hành.

Các environment variable tuỳ chọn

Các công cụ của Go có thể được tuỳ chỉnh bằng environment variable. Quá trình build không bắt buộc biến nào cả, nhưng bạn có thể muốn đặt một số biến để ghi đè giá trị mặc định. Việc đặt các environment variable này khi chạy make.bash sẽ thiết lập giá trị mặc định cho các công cụ vừa được build. Khi dùng các công cụ đó, bạn có thể ghi đè các giá trị mặc định này cho một lần build cụ thể, như được mô tả trong tài liệu của câu lệnh go.

  • $GOROOT

    Thư mục gốc của cây Go, thường là $HOME/go1.X. Giá trị của nó được nhúng vào cây thư mục khi biên dịch, và mặc định là thư mục cha của thư mục nơi all.bash được chạy. Bạn không cần đặt biến này trừ khi muốn chuyển qua lại giữa nhiều bản sao cục bộ của repository.

  • $GOOS và $GOARCH

    Tên của hệ điều hành đích và kiến trúc biên dịch. $GOOS mặc định là giá trị của runtime.GOOS trong toolchain bootstrap. $GOARCH mặc định là giá trị của $GOHOSTARCH, được mô tả bên dưới.

    Các lựa chọn cho $GOOS là android, darwin, dragonfly, freebsd, illumos, ios, js, linux, netbsd, openbsd, plan9, solaris, wasip1 và windows.

    Các lựa chọn cho $GOARCH là amd64 (x86 64-bit, port hoàn thiện nhất), 386 (x86 32-bit), arm (ARM 32-bit), arm64 (ARM 64-bit), ppc64le (PowerPC 64-bit, little-endian), ppc64 (PowerPC 64-bit, big-endian), mips64le (MIPS 64-bit, little-endian), mips64 (MIPS 64-bit, big-endian), mipsle (MIPS 32-bit, little-endian), mips (MIPS 32-bit, big-endian), s390x (IBM System z 64-bit, big-endian), và wasm (WebAssembly 32-bit).

    Các tổ hợp hợp lệ của $GOOS và $GOARCH là:

    $GOOS $GOARCH
    aix ppc64
    android 386
    android amd64
    android arm
    android arm64
    darwin amd64
    darwin arm64
    dragonfly amd64
    freebsd 386
    freebsd amd64
    freebsd arm
    illumos amd64
    ios arm64
    js wasm
    linux 386
    linux amd64
    linux arm
    linux arm64
    linux loong64
    linux mips
    linux mipsle
    linux mips64
    linux mips64le
    linux ppc64
    linux ppc64le
    linux riscv64
    linux s390x
    netbsd 386
    netbsd amd64
    netbsd arm
    openbsd 386
    openbsd amd64
    openbsd arm
    openbsd arm64
    plan9 386
    plan9 amd64
    plan9 arm
    solaris amd64
    wasip1 wasm
    windows 386
    windows amd64
    windows arm
    windows arm64
  • $GOHOSTARCH

    Tên của kiến trúc biên dịch trên máy host. Giá trị mặc định là kiến trúc của hệ thống cục bộ.

    Các lựa chọn hợp lệ giống như với $GOARCH, đã liệt kê ở trên. Giá trị được chỉ định phải tương thích với hệ thống cục bộ. Chẳng hạn, bạn không nên đặt $GOHOSTARCH thành arm trên một hệ thống x86.

  • $GO386 (chỉ dành cho 386, mặc định là sse2)

    Biến này điều khiển cách gc hiện thực các phép tính dấu phẩy động.

    • GO386=softfloat: dùng các phép dấu phẩy động bằng phần mềm; hỗ trợ được mọi chip x86 (Pentium MMX trở lên).
    • GO386=sse2: dùng SSE2 cho các phép dấu phẩy động; hiệu năng tốt hơn nhưng chỉ có trên Pentium 4/Opteron/Athlon 64 trở lên.
  • $GOARM (chỉ dành cho arm; mặc định được tự động nhận diện nếu build trên chính bộ xử lý đích, nếu không thì là 7)

    Biến này đặt phiên bản kiến trúc bộ đồng xử lý dấu phẩy động ARM mà run-time nên nhắm tới. Nếu bạn biên dịch ngay trên hệ thống đích, giá trị của nó sẽ được tự động nhận diện.

    • GOARM=5: dùng dấu phẩy động bằng phần mềm; khi CPU không có bộ đồng xử lý VFP
    • GOARM=6: chỉ dùng VFPv1; mặc định khi cross compile; thường là nhân ARM11 trở lên (VFPv2 trở lên cũng được hỗ trợ)
    • GOARM=7: dùng VFPv3; thường là nhân Cortex-A

    Nếu còn phân vân, hãy để biến này không được đặt, và điều chỉnh khi cần vào lần đầu bạn chạy tệp thực thi Go. Trang GoARM trên wiki cộng đồng Go chứa thêm chi tiết về việc Go hỗ trợ ARM.

  • $GOARM64 (chỉ dành cho arm64; mặc định là v8.0)

    Biến này đặt phiên bản kiến trúc ARM64 để biên dịch. Xem trang MinimumRequirements trên Go wiki để biết các lựa chọn được phép.

  • $GOAMD64 (chỉ dành cho amd64; mặc định là v1)

    Biến này đặt mức vi kiến trúc để biên dịch. Các giá trị hợp lệ là v1 (mặc định), v2, v3, v4. Xem trang MinimumRequirements trên Go wiki để biết thêm thông tin.

  • $GOMIPS (chỉ dành cho mips và mipsle)
    $GOMIPS64 (chỉ dành cho mips64 và mips64le)

    Các biến này quy định có dùng lệnh dấu phẩy động hay không. Đặt thành “hardfloat” để dùng lệnh dấu phẩy động; đây là mặc định. Đặt thành “softfloat” để dùng dấu phẩy động bằng phần mềm.

  • $GOPPC64 (chỉ dành cho ppc64 và ppc64le)

    Biến này đặt mức bộ xử lý (tức phiên bản Instruction Set Architecture) mà compiler sẽ nhắm tới. Mặc định là power8.

    • GOPPC64=power8: sinh lệnh ISA v2.07
    • GOPPC64=power9: sinh lệnh ISA v3.00
  • $GORISCV64 (chỉ dành cho riscv64)

    Biến này đặt profile ứng dụng chế độ người dùng của RISC-V để biên dịch. Mặc định là rva20u64.

    • GORISCV64=rva20u64: chỉ dùng các phần mở rộng RISC-V bắt buộc trong profile RVA20U64
    • GORISCV64=rva22u64: chỉ dùng các phần mở rộng RISC-V bắt buộc trong profile RVA22U64
    • GORISCV64=rva23u64: chỉ dùng các phần mở rộng RISC-V bắt buộc trong profile RVA23U64
  • $GOWASM (chỉ dành cho wasm)

    Biến này là danh sách ngăn cách bằng dấu phẩy các tính năng WebAssembly thử nghiệm mà binary WebAssembly được biên dịch ra được phép dùng. Mặc định là không dùng tính năng thử nghiệm nào.

Lưu ý rằng $GOARCH và $GOOS xác định môi trường đích, chứ không phải môi trường bạn đang chạy. Trên thực tế, bạn luôn luôn đang cross-compile. Khi nói kiến trúc, chúng tôi muốn nói tới loại binary mà môi trường đích có thể chạy được: một hệ thống x86-64 chạy hệ điều hành chỉ 32-bit phải đặt GOARCH thành 386, chứ không phải amd64.

Xin nhắc lại, không biến nào trong số này bắt buộc phải đặt để build, cài đặt và phát triển cây Go.

Nội dung gốc: Go Documentation © The Go Authors, giấy phép CC BY 3.0. Bản dịch và ghi chú: Lê Văn Dũng.