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.
-
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:
$ cdTrê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.
-
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 -
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/helloThê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/reverseTạ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.
-
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. -
Thêm module vào workspace
Repo Git vừa được checkout vào
./example. Mã nguồn của modulegolang.org/x/example/hellonằm trong./example/hello. Hãy thêm nó vào workspace:$ go work use ./example/helloLệnh
go work usethê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/hellolẫn modulegolang.org/x/example/hello, module sau cung cấp packagegolang.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
reversecủ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ệnhgo get. -
Thêm hàm mới.
Chúng ta sẽ thêm vào package
golang.org/x/example/hello/reversemột hàm mới để đảo ngược một số.Tạo tệp mới tên
int.gotrong thư mụcworkspace/example/hello/reversevớ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 } -
Sửa chương trình hello để dùng hàm đó.
Sửa nội dung tệp
workspace/hello/hello.gothà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ịusechodirvào tệpgo.worknếu thư mục đó tồn tại, và gỡ bỏ thư mụcusenếu thư mục trong đối số không tồn tại. Cờ-rsẽ duyệt đệ quy các thư mục con củadir.go work editsửa tệpgo.work, tương tự nhưgo mod editgo 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.