Metamethod __index
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 18 trên 54.
Bây giờ bạn đã biết cách gắn metatable vào bảng, đã đến lúc tìm hiểu về metamethod quan trọng nhất: __index. Metamethod này điều khiển điều gì xảy ra khi bạn truy cập một khóa không tồn tại trong bảng.
Thông thường, khi bạn tìm một khóa không có trong bảng, Lua trả về nil. Nhưng nếu bảng có metatable với trường __index, Lua sẽ kiểm tra trường đó. Nếu __index trỏ đến một bảng khác, Lua sẽ tìm khóa trong bảng đó:
local defaults = {
health = 100,
speed = 10
}
local player = {name = "Alice"}
local meta = {__index = defaults}
setmetatable(player, meta)
print(player.name) -- Đầu ra: Alice
print(player.health) -- Đầu ra: 100Trong ví dụ này, player chỉ có khóa name. Khi bạn truy cập player.health, Lua không tìm thấy thuộc tính này trong player, nên kiểm tra trường __index của metatable. Vì __index trỏ đến bảng defaults, Lua tìm ở đó và thấy health = 100.
Điều này tạo ra cơ chế dự phòng, trong đó một bảng có thể cung cấp giá trị mặc định cho bảng khác. Bảng ban đầu vẫn giữ các giá trị của mình, nhưng mọi khóa còn thiếu sẽ tự động được tra cứu trong bảng dự phòng.
Thử thách
DễViết hàm createCharacterWithDefaults nhận name và level, rồi trả về một bảng nhân vật có các giá trị chỉ số mặc định.
Tạo một bảng nhân vật với tên và cấp độ được cung cấp. Dùng metatable với __index để cung cấp các giá trị mặc định cho mọi chỉ số còn thiếu (máu, năng lượng, sức mạnh).
Logic:
- Tạo một bảng giá trị mặc định với các khóa:
health = 100,mana = 50,strength = 10 - Tạo một bảng nhân vật với các khóa:
name(tên được cung cấp) vàlevel(cấp độ được cung cấp) - Tạo một metatable có
__indextrỏ đến bảng giá trị mặc định - Gắn metatable vào bảng nhân vật bằng
setmetatable() - Trả về bảng nhân vật
Tham số:
name(chuỗi): Tên nhân vậtlevel(số): Cấp độ của nhân vật
Giá trị trả về: Một bảng nhân vật có tên, cấp độ và các chỉ số mặc định có thể truy cập thông qua metatable (bảng)
Tự làm thử
function createCharacterWithDefaults(name, level)
-- 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