Phong Cách CamelCase Và Snake_case Trong Đặt Tên Biến - nói dối e blog

Phong Cách CamelCase Và Snake_case Trong Đặt Tên Biến

Thực ra tôi không quá câu nệ về kiểu trình bày mã nguồn như việc dùng khoảng trắng hay tab để thụt lề, vị trí đặt dấu ngoặc nhọn ở cuối dòng hay dòng mới, hay việc dùng gạch nối giữa các từ hay viết liền theo kiểu CamelCase. Khi làm việc độc lập, mỗi người sẽ có thói quen riêng, nhưng trong môi trường nhóm, tôi hoàn toàn chấp nhận việc mỗi người theo phong cách quen thuộc của họ.

Đây là những yếu tố bề ngoài, không ảnh hưởng đến cấu trúc chương trình, thậm chí không làm giảm tính dễ đọc. Ngược lại, sự khác biệt về phong cách còn giúp nhận diện tác giả đoạn code, khi đọc có thể “truy nguyên” tác giả dễ dàng hơn cả dùng lệnh git blame nữa.

Vấn đề CamelCase và Snake_case khiến tôi bận tâm gần đây là khi phát triển dự án bgfxidl. Tác giả dự án bgfx muốn dùng ngôn ngữ IDL để mô tả và sinh ra các macro định nghĩa. Khi thiết kế cú pháp IDL, tôi phải quyết định giữa hai phong cách đặt tên này.

Trước đó, phần IDL đã có của bgfx dùng CamelCase, sau đó chuyển sang giao diện C bằng cách chuyển thành Snake_case. Vì vậy lựa chọn tự nhiên là tiếp tục dùng CamelCase. Tuy nhiên có điểm khác biệt nhỏ: hiện tại các macro định nghĩa của bgfx chỉ có phiên bản C (dùng Snake_case), nhưng dự kiến sẽ bổ sung phiên bản C++ dùng CamelCase cho hằng số. Việc duy trì hai phiên bản này trước đây rất tốn kém khi chưa có IDL, nên chỉ tồn tại phiên bản C duy nhất.

Lần này không có chuẩn mực nào để tham chiếu. Khi dùng CamelCase cho loạt macro này, tôi phát hiện ra một điểm bất cập khi có mặt các con số. Đây là một hạn chế đáng chú ý. Trong các dự án C trước đây, tôi luôn dùng Snake_case nên chưa từng gặp phải vấn đề này.

Trong Snake_case, ranh giới giữa các từ rất rõ ràng nhờ ký tự gạch nối. Nhưng chữ cái Latinh đã có phân biệt hoa thường, hoàn toàn có thể dùng chữ hoa để phân cách từ, tạo nên kiểu viết gọn gàng hơn. Tuy nhiên có hai trường hợp ngoại lệ cần lưu ý.

Thứ nhất: các từ viết tắt bằng chữ in hoa hoàn toàn
Ví dụ như RGB (viết tắt của RedGreenBlue). Khi chuyển đổi giữa hai phong cách, RGB nên được xem là một từ hay ba từ riêng biệt? Nếu chuyển CamelCase sang Snake_case, nên viết r_g_b, rgb hay RGB? Tôi cho rằng không nên tách r_g_b vì đã là từ viết tắt. Việc dùng chữ thường hay hoa có thể bàn bạc, nhưng tôi thiên về việc giữ nguyên từ viết tắt như một từ duy nhất.

Vấn đề phát sinh khi từ viết tắt kết hợp với từ tiếp theo. Ví dụ “RGBBitmap” nên phân tách như thế nào? Tôi đưa ra quy tắc: chuỗi chữ thường luôn kết hợp với chữ hoa đứng trước thành một từ. Một giải pháp khác là viết tắt theo kiểu Rgb thay vì RGB, nhưng cách này chưa phổ biến.

Thứ hai: cách xử lý các con số
Số không có chữ hoa/thường nên khó xác định ranh giới từ. Thông thường số không đứng riêng lẻ, ví dụ “3d” rõ ràng là một từ. Ban đầu tôi định coi số như chữ hoa để dễ dùng regex chuyển đổi, như D3D12 sẽ thành một từ hoàn chỉnh. Tuy nhiên gặp phải trường hợp như “Int32” - trong Snake_case ta không viết int_32 mà gộp thành int32.

Tôi nhận ra không thể dựa vào chữ cái đứng trước số để phân tách từ. Ví dụ “Create3d” rõ ràng là “Create” + “3d” chứ không phải “Create3” + “d”. Cuối cùng tôi chọn giải pháp kết hợp cả hai phong cách trong dự án bgfxidl: coi số như chữ thường, trừ khi có gạch nối phía trước thì mới xem như chữ hoa phân cách từ.

Cơ chế chuyển đổi cụ thể:

  • Khi chuyển từ IDL sang CamelCase: đơn giản bỏ hết gạch nối
  • Khi chuyển sang Snake_case: phân tách theo chữ hoa hoặc gạch nối trước số

Ví dụ minh họa:

  • Texture_2d → CamelCase: Texture2D | Snake_case: TEXTURE_2D
  • Format_8x1 → CamelCase: Format8x1 | Snake_case: FORMAT_8X1
  • Uint10 → CamelCase: Uint10 | Snake_case: UINT10

Giải pháp này giúp đảm bảo tính nhất quán trong toàn hệ thống, đồng thời giải quyết triệt để các trường hợp đặc biệt liên quan đến viết tắt và số học.

0%