Metamethod số học phần 1
Thuộc phần Logic và luồng chương trình trong hành trình Lua của Coddy. Bài học 21 trên 54.
Bạn đã học cách tùy chỉnh nội dung hiển thị khi in một bảng bằng __tostring. Giờ đây, bạn sẽ khám phá cách metatable cũng có thể xác định điều gì xảy ra khi bạn dùng các toán tử số học như + và - với các bảng.
Thông thường, nếu bạn thử cộng hai bảng bằng toán tử +, Lua sẽ báo lỗi vì nó không biết cách cộng các bảng. Nhưng với các metamethod số học, bạn có thể định nghĩa chính xác phép cộng có nghĩa là gì đối với các kiểu dữ liệu tùy chỉnh của mình.
Metamethod __add điều khiển cách phép cộng hoạt động. Khi Lua gặp toán tử + giữa hai giá trị và ít nhất một giá trị có metatable chứa __add, Lua gọi hàm đó thay vì báo lỗi:
local v1 = {x = 3, y = 4}
local v2 = {x = 1, y = 2}
local meta = {
__add = function(a, b)
return {x = a.x + b.x, y = a.y + b.y}
end
}
setmetatable(v1, meta)
setmetatable(v2, meta)
local v3 = v1 + v2
print(v3.x, v3.y) -- Đầu ra: 4 6Hàm __add nhận hai đối số: toán hạng bên trái và toán hạng bên phải. Trong ví dụ này, hàm tạo một bảng mới với các giá trị x và y là tổng của các giá trị tương ứng từ cả hai bảng đầu vào.
Tương tự, phương thức siêu dữ liệu __sub điều khiển phép trừ bằng toán tử -:
local meta = {
__sub = function(a, b)
return {x = a.x - b.x, y = a.y - b.y}
end
}
setmetatable(v1, meta)
setmetatable(v2, meta)
local v3 = v1 - v2
print(v3.x, v3.y) -- Đầu ra: 2 2Khả năng định nghĩa hành vi tùy chỉnh cho toán tử này được gọi là nạp chồng toán tử (operator overloading).
Thử thách
DễViết một hàm addVectors nhận x1, y1, x2 và y2, rồi trả về kết quả cộng hai vector.
Tạo hai bảng vector với tọa độ đã cho, gắn metatable có phương thức metamethod __add để cho phép cộng vector, cộng chúng bằng toán tử +, rồi trả về kết quả dưới dạng chuỗi được định dạng.
Logic:
- Tạo bảng vector thứ nhất với các khóa
x = x1vày = y1 - Tạo bảng vector thứ hai với các khóa
x = x2vày = y2 - Tạo một metatable có
__add, nhận hai vector và trả về một bảng mới vớix = a.x + b.xvày = a.y + b.y - Gắn metatable vào cả hai bảng vector bằng
setmetatable() - Cộng hai vector bằng
v1 + v2 - Trả về kết quả dưới dạng chuỗi theo định dạng
"x y"(giá trị x và y được phân cách bằng một dấu cách)
Tham số:
x1(number): Tọa độ x của vector thứ nhấty1(number): Tọa độ y của vector thứ nhấtx2(number): Tọa độ x của vector thứ haiy2(number): Tọa độ y của vector thứ hai
Giá trị trả về: Tổng của hai vector dưới dạng chuỗi theo định dạng "x y" (chuỗi)
Tự làm thử
function addVectors(x1, y1, x2, y2)
-- Viết code ở đây
end
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Logic và luồng chương trình
4Giới thiệu về metatable
Metatable là gì?setmetatable và getmetatableMetamethod __indexMetamethod __newindexMetamethod __tostringMetamethod số học phần 1Metamethod số học phần 2Ôn tập: bảng chỉ đọc2Các hàm khác của thư viện table
table.concat()Tạo table và unpack()table.sort()Sắp xếp tùy chỉnh bằng hàmÔn tập: Bảng điểm cao5Dự án: Bộ máy trò chơi phiêu lưu bằng văn bản
Thiết lập dự án: Căn phòngLiên kết các phòngTự luyện tập: Trình biên dịch Lua online