☰ 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ữ
Hướng dẫn (Tutorials)

Hướng dẫn: Bắt đầu với workspace nhiều module

Bản dịch từ go.dev/doc/tutorial/workspaces

Bài hướng dẫn này giới thiệu những điều cơ bản về workspace nhiều module trong Go. Với workspace nhiều module, bạn có thể báo cho lệnh go biết rằng bạn đang viết mã trong nhiều module cùng lúc, nhờ đó build và chạy mã trong những module đó một cách dễ dàng.

Trong bài hướng dẫn này, bạn sẽ tạo hai module trong một workspace nhiều module dùng chung, thực hiện thay đổi xuyên suốt các module đó, và thấy kết quả của những thay đổi ấy khi build.

Lưu ý: Xem các bài hướng dẫn khác tại Hướng dẫn.

Yêu cầu trước khi bắt đầu

  • Go. Chúng tôi khuyến nghị dùng phiên bản Go mới nhất để theo bài hướng dẫn này. Xem hướng dẫn cài đặt tại Cài đặt Go.
  • Một công cụ để soạn mã. Bất kỳ trình soạn thảo văn bản nào bạn có đều dùng được.
  • Một cửa sổ dòng lệnh. Go chạy tốt với mọi terminal trên Linux và Mac, và với PowerShell hoặc cmd trên Windows.

Tạo một module cho mã của bạn

Để bắt đầu, hãy tạo một module cho đoạn mã bạn sắp viết.

  1. Mở cửa sổ dòng lệnh và chuyển về thư mục home của bạn.

    Trên Linux hoặc Mac:

    $ cd

    Trên Windows:

    C:\> cd %HOMEPATH%

    Phần còn lại của bài hướng dẫn sẽ hiển thị dấu $ làm dấu nhắc lệnh. Các lệnh bạn dùng cũng chạy được trên Windows.

  2. Từ dòng lệnh, tạo một thư mục cho mã của bạn, đặt tên là workspace.

    $ mkdir workspace
    $ cd workspace
  3. Khởi tạo module

    Ví dụ của chúng ta sẽ tạo một module mới tên hello, module này sẽ phụ thuộc vào module golang.org/x/example.

    Tạo module hello:

    $ mkdir hello
    $ cd hello
    $ go mod init example.com/hello
    go: creating new go.mod: module example.com/hello

    Thêm phụ thuộc vào package golang.org/x/example/hello/reverse bằng cách dùng go get.

    $ go get golang.org/x/example/hello/reverse

    Tạo tệp hello.go trong thư mục hello với nội dung sau:

    package main
    
    import (
        "fmt"
    
        "golang.org/x/example/hello/reverse"
    )
    
    func main() {
        fmt.Println(reverse.String("Hello"))
    }

    Bây giờ, hãy chạy chương trình hello:

    $ go run .
    olleH

Tạo workspace

Ở bước này, chúng ta sẽ tạo tệp go.work để chỉ định một workspace chứa module vừa rồi.

Khởi tạo workspace

Trong thư mục workspace, chạy:

$ go work init ./hello

Lệnh go work init báo cho go tạo tệp go.work cho một workspace chứa các module nằm trong thư mục ./hello.

Lệnh go sinh ra tệp go.work trông như thế này:

go 1.18

use ./hello

Tệp go.work có cú pháp tương tự go.mod.

Chỉ thị go cho Go biết tệp này nên được diễn giải theo phiên bản Go nào. Nó tương tự chỉ thị go trong tệp go.mod.

Chỉ thị use cho Go biết rằng module nằm trong thư mục hello sẽ là module chính khi build.

Nhờ vậy, ở bất kỳ thư mục con nào của workspace, module đó đều có hiệu lực.

Chạy chương trình trong thư mục workspace

Trong thư mục workspace, chạy:

$ go run ./hello
olleH

Lệnh Go đưa toàn bộ các module trong workspace vào làm module chính. Điều này cho phép chúng ta tham chiếu tới một package trong module, kể cả từ bên ngoài module đó. Chạy lệnh go run bên ngoài module hoặc bên ngoài workspace sẽ báo lỗi, vì lệnh go sẽ không biết phải dùng những module nào.

Tiếp theo, chúng ta sẽ thêm một bản sao cục bộ của module golang.org/x/example/hello vào workspace. Module đó được lưu trong một thư mục con của repository Git go.googlesource.com/example. Sau đó chúng ta sẽ thêm một hàm mới vào package reverse để dùng thay cho String.

Tải về và sửa đổi module golang.org/x/example/hello

Ở bước này, chúng ta sẽ tải về một bản sao của repo Git chứa module golang.org/x/example/hello, thêm nó vào workspace, rồi bổ sung cho nó một hàm mới mà chương trình hello sẽ dùng.

  1. Clone repository

    Từ thư mục workspace, chạy lệnh git để clone repository:

    $ git clone https://go.googlesource.com/example
    Cloning into 'example'...
    remote: Total 165 (delta 27), reused 165 (delta 27)
    Receiving objects: 100% (165/165), 434.18 KiB | 1022.00 KiB/s, done.
    Resolving deltas: 100% (27/27), done.
  2. Thêm module vào workspace

    Repo Git vừa được checkout vào ./example. Mã nguồn của module golang.org/x/example/hello nằm trong ./example/hello. Hãy thêm nó vào workspace:

    $ go work use ./example/hello

    Lệnh go work use thêm một module mới vào tệp go.work. Giờ tệp đó sẽ trông như sau:

    go 1.18
    
    use (
        ./hello
        ./example/hello
    )

    Workspace bây giờ chứa cả module example.com/hello lẫn module golang.org/x/example/hello, module sau cung cấp package golang.org/x/example/hello/reverse.

    Điều này cho phép chúng ta dùng đoạn mã mới sắp viết trong bản sao package reverse của mình, thay vì phiên bản package nằm trong module cache mà chúng ta đã tải về bằng lệnh go get.

  3. Thêm hàm mới.

    Chúng ta sẽ thêm vào package golang.org/x/example/hello/reverse một hàm mới để đảo ngược một số.

    Tạo tệp mới tên int.go trong thư mục workspace/example/hello/reverse với nội dung sau:

    package reverse
    
    import "strconv"
    
    // Int returns the decimal reversal of the integer i.
    func Int(i int) int {
        i, _ = strconv.Atoi(String(strconv.Itoa(i)))
        return i
    }
  4. Sửa chương trình hello để dùng hàm đó.

    Sửa nội dung tệp workspace/hello/hello.go thành như sau:

    package main
    
    import (
        "fmt"
    
        "golang.org/x/example/hello/reverse"
    )
    
    func main() {
        fmt.Println(reverse.String("Hello"), reverse.Int(24601))
    }

Chạy mã trong workspace

Từ thư mục workspace, chạy

$ go run ./hello
olleH 10642

Lệnh Go tìm thấy module example.com/hello được chỉ định trên dòng lệnh, nằm trong thư mục hello mà tệp go.work đã khai báo, và cũng tương tự như vậy, nó phân giải lệnh import golang.org/x/example/hello/reverse dựa vào tệp go.work.

Có thể dùng go.work thay cho việc thêm các chỉ thị replace khi cần làm việc xuyên suốt nhiều module.

Vì hai module nằm trong cùng một workspace nên rất dễ thay đổi ở module này rồi dùng ngay ở module kia.

Bước tiếp theo trong tương lai

Bây giờ, để phát hành các module này một cách đúng đắn, chúng ta sẽ cần tạo một bản phát hành cho module golang.org/x/example/hello, chẳng hạn ở phiên bản v0.1.0. Việc này thường được thực hiện bằng cách gắn tag cho một commit trên repository quản lý phiên bản của module. Xem tài liệu về quy trình phát hành module để biết thêm chi tiết. Sau khi đã phát hành xong, chúng ta có thể nâng yêu cầu phiên bản đối với module golang.org/x/example/hello trong hello/go.mod:

cd hello
go get golang.org/x/example/[email protected]

Nhờ vậy, lệnh go có thể phân giải các module bên ngoài workspace một cách đúng đắn.

Tìm hiểu thêm về workspace

Ngoài go work init mà chúng ta đã thấy ở phần trước của bài hướng dẫn, lệnh go còn có một vài lệnh con khác để làm việc với workspace:

  • go work use [-r] [dir] thêm chỉ thị use cho dir vào tệp go.work nếu thư mục đó tồn tại, và gỡ bỏ thư mục use nếu thư mục trong đối số không tồn tại. Cờ -r sẽ duyệt đệ quy các thư mục con của dir.
  • go work edit sửa tệp go.work, tương tự như go mod edit
  • go work sync đồng bộ các phụ thuộc từ danh sách build của workspace vào từng module trong workspace.

Xem Workspaces trong tài liệu tham khảo Go Modules để biết thêm chi tiết về workspace và tệp go.work.

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.