Triển Khai Nạp Chồng Hàm Trong Lua
Cảnh báo: Những nội dung dưới đây chỉ mang tính chất giải trí cá nhân, vui lòng không sử dụng vào dự án thật. Bản thân tôi cũng không ủng hộ việc tùy tiện dùng syntactic sugar để biến đổi ngôn ngữ.
Chúng ta đều biết rằng C++ hỗ trợ tính năng nạp chồng hàm (function overloading), cho phép các lập trình viên viết nhiều phiên bản hàm cùng tên nhưng khác tham số. Trình biên dịch sẽ tự động chọn hàm phù hợp dựa trên kiểu dữ liệu của đối số khi gọi hàm. Đối với các lập trình viên C++ trung thành, đây là một công cụ không thể thiếu. Nếu thiếu tính năng này, các mẫu template (template meta-programming) sẽ không thể tạo ra vô số biến thể phức tạp như hiện nay, và đương nhiên, các lập trình viên cũng sẽ không còn cơ hội ngắm nghía những đoạn mã template “thông minh” đầy hoa mỹ để tự sướng về chỉ số IQ nữa.
Tuy nhiên, các lập trình viên Lua đừng vội buồn! Lua tuy nhỏ nhưng lại là ngôn ngữ vô cùng linh hoạt. Bạn hoàn toàn có thể viết ra những đoạn mã khiến đồng nghiệp phải há hốc mồm vì ngạc nhiên. Vấn đề nạp chồng hàm tưởng chừng như chỉ có trong ngôn ngữ tĩnh, nhưng với Lua – ngôn ngữ động – chúng ta vẫn có thể mô phỏng một cách sáng tạo. Dù Lua không hỗ trợ tính toán thời gian biên dịch (trừ khi tự generate code runtime) hay quá trình liên kết tĩnh như C++.
Dưới đây là cách tôi giả lập cơ chế nạp chồng hàm trong Lua:
Mục tiêu
Chúng ta mong muốn định nghĩa các hàm cùng tên theo dạng sau:
|
|
Khi gọi hàm test
với các tham số khác nhau, hệ thống sẽ tự động chọn hàm phù hợp nhất:
|
|
Đầu ra mong đợi:
|
|
Cơ chế hoạt động
Công việc này thực ra không quá phức tạp. Chúng ta chỉ cần duy trì một bảng phân phối (dispatch table) cho mỗi hàm cần nạp chồng. Bảng này lưu trữ các hàm cùng tên nhưng có chữ ký khác nhau. Khi gọi hàm, bộ phân phối sẽ kiểm tra kiểu dữ liệu của tham số truyền vào, so sánh với các chữ ký đã đăng ký trước đó, và chọn hàm phù hợp nhất. Trường hợp không tìm thấy sự khớp nào, hệ thống sẽ ném ra một ngoại lệ để tăng cường tính an toàn khi cần kiểm tra kiểu nghiêm ngặt.
Tất nhiên, việc này sẽ kèm theo chi phí hiệu năng – đây là giá phải trả cho tính linh hoạt. Vì mục đích giải trí thuần túy nên tôi không tối ưu nhiều, xem đây như một món quà nhỏ ngày lễ.
Chúc các bạn một mùa lễ vui vẻ!
Mã nguồn tham khảo: LuaFunctionOverload
Lưu ý nhỏ: Việc thêm giá trị mặc định cho tham số cũng có thể thực hiện dễ dàng, tuy nhiên tôi sẽ không trình bày chi tiết ở đây.