1. Hiểu về Quy ước Đặt tên

Quy ước đặt tên rất quan trọng trong việc phát triển phần mềm, vì chúng cung cấp một khung để đặt tên cho biến, hàm và các định danh khác một cách đồng nhất và mô tả. Trong Go (thường được gọi là Golang), việc tuân theo quy ước đặt tên đã được thiết lập không chỉ làm cho mã của bạn dễ đọc và bảo trì mà còn cho phép người khác (và người sẽ là bạn trong tương lai) hiểu và cộng tác trên codebase của bạn một cách dễ dàng hơn.

1.1. Tại sao Đặt tên quan trọng

Trong bất kỳ ngôn ngữ lập trình nào, cách bạn đặt tên định danh có thể ảnh hưởng rất nhiều đến việc hiểu và bảo trì mã của bạn. Trong Go, nơi mà sự đơn giản và rõ ràng được nhấn mạnh, việc đặt tên đúng cách càng trở nên quan trọng hơn. Các tên mà rõ ràng truyền đạt mục đích của một biến hoặc hàm giảm thiểu sự cần thiết của các chú thích bổ sung và làm cho mã tự mô tả. Điều này quan trọng để duy trì một codebase trong thời gian và để tạo điều kiện cho việc cộng tác nhóm một cách dễ dàng.

1.2. Quy tắc chung cho việc đặt tên

Các quy tắc đặt tên của Go rất đơn giản nhưng mạnh mẽ:

  • Sử dụng tên ngắn, súc tích: Go khuyến khích sử dụng tên ngắn, đặc biệt là đối với các biến có phạm vi nhỏ. Ví dụ, i có thể được sử dụng cho việc đếm vòng lặp, nhưng nếu cần thêm rõ ràng, có thể sử dụng index hoặc counter.

  • CamelCase cho các tên nhiều từ: Khi một tên bao gồm nhiều từ, sử dụng ghi chú CamelCase. Các tên được xuất khẩu (những tên mà nên có thể truy cập bên ngoài gói) nên bắt đầu bằng một chữ cái viết hoa (MyFunction), trong khi các tên nội bộ nên bắt đầu bằng một chữ cái viết thường (myFunction).

  • Sử dụng các tên có ý nghĩa: Tên nên mô tả đủ để truyền đạt mục đích hoặc sử dụng mà không quá dài dòng. Ví dụ, CalculateNetIncome được ưa thích hơn CNI.

  • Tránh việc sử dụng dấu gạch dưới: Không giống như một số ngôn ngữ khác, quy ước của Go tránh việc sử dụng dấu gạch dưới trong tên. Thay vì record_count, bạn sẽ sử dụng recordCount.

  • Các từ viết tắt nên nhất quán: Khi sử dụng các từ viết tắt trong tên, hãy giữ chúng ở dạng viết hoa nhất quán. Với các tên được xuất khẩu, hãy sử dụng tất cả chữ in hoa (HTTPServer), và với các tên nội bộ, việc sử dụng tất cả chữ thường (httpServer) là một thực hành tiêu chuẩn.

  • Tên gói nên đơn giản: Tên gói trong Go được giữ đơn giản và viết thường, không có dấu gạch dưới hoặc viết hoa chung. Chúng nên là một từ duy nhất mô tả rõ mục đích của gói (net, os, json).

  • Đặt tên biến dựa trên loại dữ liệu: Đối với các biến đại diện cho các thể hiện của các structs, thì việc sử dụng tên của struct trong chữ thường làm tên biến là phổ biến (var user User).

Dưới đây là một ví dụ về mã Go với các chú thích giải thích về việc đặt tên:

package main

import "fmt"

type User struct {
    FirstName string
    LastName  string
    Age       int
}

func main() {
    var currentUser User // Sử dụng tên cấu trúc bằng chữ thường làm tên biến.
    currentUser.FirstName = "John"
    currentUser.LastName = "Doe"
    currentUser.Age = 30

    fmt.Println(formatUserDetails(currentUser))
}

// formatUserDetails nhận một cấu trúc User làm đầu vào và trả về một chuỗi được định dạng.
// Tên hàm bắt đầu bằng một chữ cái thường vì nó không được xuất khẩu (riêng tư).
func formatUserDetails(u User) string {
    return fmt.Sprintf("Tên: %s %s, Tuổi: %d", u.FirstName, u.LastName, u.Age)
}

Tuân thủ quy ước đặt tên này sẽ cải thiện rất nhiều chất lượng mã Go của bạn thông qua việc làm cho nó dễ đọc và bảo trì hơn.

2. Định danh trong Go

Khi bắt đầu hành trình của bạn với Go, việc hiểu vai trò của các định danh là vô cùng quan trọng. Các định danh là các tên bạn gán cho các phần tử khác nhau trong mã của bạn, chẳng hạn như biến, hàm và hằng số. Việc chọn các tên có ý nghĩa và nhất quán giúp làm cho mã của bạn dễ đọc và bảo trì hơn.

2.1. Quy ước đặt tên biến

Trong Go, tên biến phải bắt đầu bằng một chữ cái hoặc dấu gạch dưới, theo sau bởi bất kỳ kết hợp nào của chữ cái, chữ số hoặc dấu gạch dưới. Tuy nhiên, không khuyến khích bắt đầu bằng dấu gạch dưới vì thường dành cho các trường hợp đặc biệt.

Thực hành tốt:

  • Sử dụng các tên ngắn, mô tả.
  • Bắt đầu bằng chữ thường cho phạm vi cấp độ gói.
  • Sử dụng CamelCase cho các tên nhiều từ (ví dụ: totalAmount).
  • Đối với các biến được xuất khẩu (có thể truy cập bên ngoài gói), bắt đầu bằng chữ in hoa.

Ví dụ:

var userName string // biến không được xuất khẩu
var UserAge int     // biến được xuất khẩu

Các chú thích trong mã làm sáng tỏ sự khác biệt giữa các biến được

### 2.2. Quy ước đặt tên hàm

Trong Go, các hàm được đặt tên theo các quy tắc tương tự như biến. Tên nên phản ánh mục đích của hàm và phạm vi của nó quyết định việc viết hoa chữ cái đầu tiên.

**Thực hành tốt:**
- Sử dụng tên mô tả một cách rõ ràng mục đích của hàm.
- Bắt đầu bằng chữ thường cho các hàm nội bộ.
- Sử dụng PascalCase (bắt đầu bằng chữ in hoa) cho các hàm được xuất ra.
- Giữ cho tên hàm ngắn gọn nhưng có ý nghĩa.

**Ví dụ:**
```go
func calculateTotal(price int, quantity int) int { // hàm nội bộ
    return price * quantity
}

func CalculateDiscount(totalPrice int) float64 { // hàm được xuất ra
    return totalPrice * 0.1
}

Các comment giải thích việc truy cập vào hàm dựa trên việc viết hoa chữ cái đầu, và cung cấp một cái nhìn ngắn gọn vào mục đích của nó.

2.3. Quy ước đặt tên hằng số

Hằng số là các giá trị không thể thay đổi một khi đã được định nghĩa. Trong Go, hằng số được khai báo bằng từ khóa const và có thể là ký tự, chuỗi, boolean, hoặc giá trị số.

Thực hành tốt:

  • Sử dụng tất cả chữ cái in hoa với dấu gạch dưới để phân cách (ví dụ như MAX_LIMIT).
  • Đối với hằng số được đánh dấu số thứ tự, sử dụng enumerator iota.
  • Hằng số được xuất ra nên bắt đầu bằng chữ in hoa.

Ví dụ:

const MAX_RETRY_COUNT int = 3 // hằng số được xuất ra

type ByteSize float64
const (
    _           = iota // bỏ qua giá trị đầu tiên bằng cách gán cho biến định danh trắng
    KB ByteSize = 1 << (10 * iota)
    MB
    GB
    TB
)

Ví dụ này biểu diễn cách định nghĩa các hằng số đơn giản và một tập hợp các hằng số liên quan bằng cách sử dụng iota cho kích thước byte.

3. Quy ước đặt tên cho các loại

... (phần còn lại bị cắt)

4.2. Các Phương Pháp Tốt Nhất cho Các Bộ Nhận Dạng Đã Xuất Khoản

Khi đặt tên cho các bộ nhận dạng đã xuất khoản, việc tuân theo một số phương pháp tốt nhất rất quan trọng để đảm bảo mã của bạn dễ đọc và hiểu được bởi người khác:

  • Sự Rõ Ràng Hơn Là Súc tích: Chọn các tên rõ ràng và mô tả hơn là những tên ngắn gọn và bí ẩn. Ví dụ, CalculateArea được ưa chuộng hơn là CalcA.
  • Tính Đồng Nhất: Hãy đồng nhất với các quy ước đặt tên trong toàn bộ mã nguồn của bạn. Nếu bạn bắt đầu đặt tên các thực thể tương tự theo mẫu cụ thể, hãy tuân theo chúng.
  • Tránh Sự Trùng Lặp Không Cần Thiết: Không lặp lại tên gói trong tên bộ nhận dạng. Ví dụ, sử dụng geometry.Rectangle thay vì geometry.GeometryRectangle.
  • Xem Xét Bối Cảnh: Tên của các bộ nhận dạng cần phản ánh được bối cảnh sử dụng của chúng. Tránh các tên có thể gây hiểu lầm hoặc mơ hồ.
  • Bình Luận Văn Bản Tài Liệu: Sử dụng bình luận để mô tả các bộ nhận dạng đã xuất khoản, giải thích chúng làm gì và cách sử dụng chúng.

Ví dụ:

package geometry

// CalculateArea trả về diện tích của hình chữ nhật.
func (r Rectangle) CalculateArea() float64 {
    return r.Length * r.Width
}

Trong ví dụ này, CalculateArea là một hàm đã xuất khoản có tên rõ ràng, mô tả và kèm theo một bình luận văn bản tài liệu giải thích mục đích của nó.

5. Quy ước Đặt Tên Trong Thực Tiễn

Trong chương này, chúng ta sẽ đàm phán về việc áp dụng quy ước đặt tên trong Go trong các tình huống thực tế. Hiểu và tuân theo những quy ước này rất quan trọng vì nó đảm bảo mã của bạn tuân theo quy ước, dễ đọc và bảo trì.

5.1. Những Sai Lầm Phổ Biến và Cách Tránh Chúng

Đặt tên biến, hàm và các bộ nhận dạng khác thường bị đánh giá thấp về tầm quan trọng của nó. Những sai lầm phổ biến bao gồm:

  • Sử dụng các tên chung chung: Tên như data hoặc info không mô tả và có thể gây nhầm lẫn.
  • Tên quá dài: Mặc dù các tên mô tả tốt, nhưng tên quá dài có thể làm rối. Hãy đạt được một sự cân bằng.
  • Gạch dưới trong các bộ nhận dạng nhiều từ: Go ưa thích camelCase cho tên biến và PascalCase cho các hàm và kiểu dữ liệu đã xuất khoản.
  • Mẫu đặt tên không đồng nhất: Tính đồng nhất trong quy ước đặt tên giúp hiểu cấu trúc mã nguồn nhanh chóng.

Mẹo để tránh những rủi ro này:

  • Sử dụng các tên súc tích và mô tả. Ví dụ, thay vì data, hãy sử dụng userData nếu nó chứa thông tin về người dùng.
  • Tuân theo quy ước của Go cho viết tắt; giữ chúng in hoa, như HTTPServer thay vì HttpServer.
  • Đối với các biến và hằng số ở mức gói không được xuất khoản, hãy giữ tên ngắn vì chúng có phạm vi hạn chế.

5.2. Tái Cấu Trúc để Có Tên Tốt Hơn

Việc tái cấu trúc mã để cải thiện tên bộ nhận dạng có thể cải thiện đáng kể khả năng đọc mã. Dưới đây là cách bạn có thể làm điều này một cách an toàn:

  1. Sử dụng các tên mô tả: Đổi tên để diễn đạt rõ ràng những gì chúng đại diện hoặc làm. Ví dụ, đổi tên hàm từ Process thành ProcessUserInput nếu đó là công việc của nó.
  2. Tận dụng các công cụ: Sử dụng các công cụ như gorename cho phép đổi tên an toàn bằng cách phân tích mã Go theo mặt ngữ nghĩa chứ không phải theo mặt văn bản.
  3. Xem xét với đồng nghiệp: Đôi khi những gì hợp lý với bạn có thể không rõ ràng đối với người khác. Đánh giá từ đồng nghiệp có thể giúp nhận diện tên mơ hồ.
  4. Lặp lại thông tin phản hồi: Sau khi thay đổi, thu thập phản hồi từ người dùng mã nguồn và lặp lại việc đặt tên nếu cần thiết.

Bằng cách tuân theo những kỹ thuật này, bạn sẽ đảm bảo rằng mã nguồn Go của bạn luôn sạch sẽ, dễ hiểu và có thể bảo trì được.