Menu
CoddyTech

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: 100

Trong 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.

challenge icon

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ó __index trỏ đế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ật
  • level (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
quiz iconTự kiểm tra

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

Tự luyện tập: Trình biên dịch Lua online