Như mọi tài liệu hướng dẫn lập trình các ngôn ngữ khác, chúng ta cùng bắt đầu lập trình Go với chương trình đơn giản hiển thị chuỗi Hello Go world! lên màn hình.
Trước tiên, chúng ta cần thống nhất một số thuật ngữ để tiện trao đổi:
- Dự án (project) là chỉ toàn bộ các file mã nguồn (có phần mở rộng là .go), tài nguyên liên quan chúng ta tạo nên thông qua giai đoạn viết mã nguồn, tạo file tài nguyên như hình ảnh, âm thanh, v.v...
- Chương trình (program) hay ứng dụng (application) là để chỉ sản phẩm tạo thành của dự án sau khi được biên dịch và được lưu dưới dạng file thực thi. Chương trình thường được sử dụng với các sản phẩm không có giao diện người dùng và thường được gọi chạy ngầm hoặc chạy từ dòng lệnh (Command Prompt trên Windows hay Terminal trên Linux, OS X). Ngược lại ứng dụng để chỉ các sản phẩm có giao diện đồ họa.
- File thư viện (library file) là các file được các dự án khác sử dụng và khi biên dịch, trình biên dịch Go sẽ ghép mã máy đã tạo của file thư viện vào chung mã máy của dự án để tạo file thực thi. File thư viện cũng được biên dịch bởi trình biên dịch Go, có phần mở rộng file là .a.
- File thực thi (executable file) là các file có thể thực thi và cho kết quả trực tiếp trên các hệ điều hành tương ứng. File thực thi là kết quả của quá trình biên dịch dự án. File thực thi có phần mở rộng là .exe trên Windows hoặc không có phần mở rộng trên các môi trường khác.
Hãy sử dụng trình soạn thảo hoặc IDE ưa thích của bạn, tạo thư mục hellogoworld trong $GOPATH/src/ và tạo file mới hellogoworld.go trong thư mục này, rồi lưu nội dung sau vào file. Lưu ý các con số đầu mỗi dòng là để đánh số dòng tiện khi tôi giải thích chứ đó không phải là một phần của mã nguồn, cần loại nó đi nếu bạn chép đoạn code này(1):
1 package main
2
3 import "fmt"
4
5 func main() {
6 fmt.Println("Hello Go world!")
7 }
Nếu sử dụng IDE chúng ta chọn chức năng build hoặc build and run để xem kết quả. Nếu sử dụng Command Prompt (Windows) hoặc Terminal (Linux, OS X) thì theo các bước sau:
- Chuyển thư mục hiện hành đến $GOPATH/src/hellogoworld (trên Windows thì đường dẫn là $GOPATH\src\hellogoworld).
- Gõ lệnh sau rồi thực thi để biên dịch file mã nguồn: go build
- Nếu có lỗi thì Go sẽ báo ngay bên dưới, còn không tức là đã thành công như hình bên dưới.
- Chạy file thực thi vừa được tạo ra: hellogoworld.exe chuỗi Hello Go world! sẽ hiện ra như hình bên dưới.
Chúng ta có thể gộp 2 bước biên dịch và thực thi ở trên bằng 1 lệnh duy nhất như sau: go run hellogoworld.go
Như vậy là chúng ta đã hoàn thành chương trình đầu tiên viết bằng ngôn ngữ Go. Bây giờ chúng ta cùng xem qua mã nguồn xem có gì đặc biệt nào!
Như vậy là chúng ta đã hoàn thành chương trình đầu tiên viết bằng ngôn ngữ Go. Bây giờ chúng ta cùng xem qua mã nguồn xem có gì đặc biệt nào!
Một file mã nguồn .go thường gồm có 3 phần:
- Khai báo package (gói) với từ khóa package.
- Khai báo các package khác cần sử dụng với từ khóa import.
- Khai báo các hằng số, kiểu dữ liệu mới, biến số và hàm chức năng.
Khai báo package
Mã nguồn Go được tổ chức trong các package như một số ngôn ngữ khác tổ chức theo thư viện hay module. Một package của Go sẽ gồm các file mã nguồn .go lưu trữ trong cùng thư mục và cùng được khai báo thuộc về package đó. Package được khai báo như dòng mã đầu tiên ở trên, với cú pháp package <tên package> và phải được khai báo ở dòng đầu tiên trong file mã nguồn.
Như trong ví dụ trên thì tên package là main một loại package đặc biệt của Go. Nó cho biết file mã nguồn này sẽ được biên dịch thành file thực thi chứ không phải là một thư viện. Và với việc khai báo package main thì file thực thi này cũng phải chứa một hàm đặc biệt là hàm main. Hàm main sẽ là nơi chương trình bắt đầu thực thi và khi thực thi hết hàm main thì chương trình cũng sẽ kết thúc. Vì lý do này, một dự án chỉ có 1 file mã nguồn chứa hàm main. Nếu không, Go sẽ báo lỗi khi biên dịch.
Khai báo các package sử dụng
Các package này được khai báo với từ khóa import. Với một package sử dụng, cách khai báo y như dòng thứ 3 ở đoạn mã bên trên. Đó là import "<tên package>". Khi sử dụng nhiều package, Go hỗ trợ cách khai báo như sau:
import ("<tên package 1>"
...
"<tên package n>"
)
Nếu sử dụng thông tin (hằng, biến, hàm) của một package nào đó mà không khai báo ở phần này, Go sẽ báo lỗi khi biên dịch. Nếu khai báo mà không sử dụng đến, Go cũng báo lỗi lúc biên dịch để tránh việc gây phức tạp và nặng nề khi biên dịch và tăng kích thước file thực thi. Go cung cấp công cụ goimports để giúp chúng ta tự động thêm package cần và loại bỏ những package thừa.
Go cung cấp hơn 100 package cho chúng ta sử dụng, nhằm giải quyết cơ bản các vấn đề gặp phải trong quá trình lập trình như nhập xuất dữ liệu, sắp xếp, xử lý chuỗi văn bản, kết nối mạng, v.v... Bên cạnh việc sử dụng các package do Go cung cấp, chúng ta có thể sử dụng các package do chúng ta tự tạo ra hoặc trên internet do người khác tạo.
Khai báo các hằng số, kiểu dữ liệu mới, biến số và hàm chức năng
Hằng số được khai báo với từ khóa const. Kiểu dữ liệu mới do chúng ta tự định nghĩa thì được khai báo với từ khóa type. Biến số thường được khai báo với từ khóa var. Hàm chức năng thì được khai báo với từ khóa func. Các từ khóa này luôn nằm đầu mỗi khai báo. Thứ tự các khai báo thì không quan trọng, không nhất thiết phải hằng số, kiểu dữ liệu, biến số, rồi mới đến hàm.
Do chương trình HelloGoworld quá đơn giản nên chúng ta không khai báo hằng số, biến số hay kiểu dữ liệu mới nào. Chúng ta sẽ tìm hiểu các khai báo và sử dụng chúng trong các bài sau. Bây giờ chúng ta tập trung vào khai báo hàm main:
5 func main() {6 fmt.Println("Hello Go world!")
7 }
Khai báo hàm nói chung và hàm main nói riêng bắt đầu bằng từ khóa func, sau đó là tên hàm chúng ta muốn đặt. Tiếp theo là danh sách các tham số được bọc trong cặp dấu ngoặc tròn (). Tiếp theo là các dữ liệu trả về cũng bọc trong cặp dấu ngoặc tròn nếu có từ 2 dữ liệu trả về. Và cuối cùng là khối xử lý chứa trong cặp ngoặc nhọn {}.
Như đã đề cập ở trên, main là hàm đặc biệt. Không chỉ vì nó là hàm đầu vào của chương trình mà cách khai báo cũng rất đặc biệt. Thứ nhất, tên bắt buộc là main. Thứ hai, hàm main không có tham số lẫn dữ liệu trả về. Đặc điểm này là rất khác với các ngôn ngữ tương tự như C hay Java vốn tham số giúp chúng ta truyền vào khi thực thi từ dòng lệnh và giá trị trả về cho chúng ta biết thông tin quan trọng khi cần lúc kết thúc chương trình, lỗi chẳng hạn. Vậy Go giải quyết 2 vấn đề này như thế nào? Go cung cấp package os hỗ trợ xử lý 2 vấn đề này:
- Muốn lấy các tham số từ dòng lệnh khi thực thi vốn được truyền vào tham số hàm main trên các ngôn ngữ khác, trên Go chúng ta dùng os.Args, sẽ nói rõ hơn khi có liên quan.
- Nếu muốn khi thực thi trả về một giá trị nào đó thì chúng ta phải dùng hàm os.Exit(<giá trị cần trả về>).
- Muốn lấy các tham số từ dòng lệnh khi thực thi vốn được truyền vào tham số hàm main trên các ngôn ngữ khác, trên Go chúng ta dùng os.Args, sẽ nói rõ hơn khi có liên quan.
- Nếu muốn khi thực thi trả về một giá trị nào đó thì chúng ta phải dùng hàm os.Exit(<giá trị cần trả về>).
Trong khối xử lý, hàm main dùng đúng một xử lý đó là in chuỗi Hello Go world! lên màn hình như thấy ở dòng số 6. Để in ra màn hình, chúng ta dùng hàm Println của package fmt. Hàm này sẽ in ra nội dung chứa trong ngoặc tròn rồi xuống dòng. fmt còn cung cấp các hàm in ra màn hình khác như Print hay Printf:
func Print(a ...interface{}) (n int, err error)
func Printf(format string, a ...interface{}) (n int, err error)
func Println(a ...interface{}) (n int, err error)
Một lưu ý dễ nhận thấy là dường như Go không dùng ký tự phân tách lệnh như các ngôn ngữ lập trình khác (thường là dấu chấm phẩy). Thực ra Go có hỗ trợ phân tách bằng dấu chấm phẩy nhưng chỉ sử dụng khi cần phân biệt nhiều lệnh trên cùng dòng. Mỗi dòng một lệnh thì không cần nhưng dùng cũng chẳng sao cả.
Bài tiếp theo là Cấu trúc file mã nguồn Go.
Tóm tắt:
- File mã nguồn Go có phần mở rộng là .go, được đặt trong thư mục con của $GOPATH/src.
- Mỗi file mã nguồn gồm 3 phần:
+ Package nó thuộc về, khai báo đầu file.
+ Package sử dụng khai báo ngay bên dưới. Mỗi file phải khai báo riêng.
+ Khai báo hằng, biến, kiểu dữ liệu mới và hàm.
- Chương trình thực thi phải có ít nhất 1 file thuộc package main và trong các file thuộc package main có 1 file chứa hàm main. Chương trình thực thi từ hàm main và kết thúc sau khi thực thi xong hàm main.
- Nếu mỗi khai báo lệnh trên từng dòng thì không cần dấu ; kết thúc lệnh.
Cảm ơn anh vì seri học Go này, em mới bắt đầu học.
ReplyDeleteCơ hội việc làm Go ở VN ntn a nhỉ, em tìm hiểu 1 số nhưng thấy ít quá.
Hiện tại thì ít bên dùng Go. Một số startup đã bắt đầu chuyển qua dùng Go cho phần back-end.
DeleteVâng anh :)
Delete