Menu
CoddyTech

Định dạng chuỗi

Thuộc phần Lập trình hướng đối tượng trong hành trình Lua của Coddy. Bài học 16 trên 70.

Khi bạn in trực tiếp một đối tượng, Lua hiển thị nội dung không hữu ích như table: 0x55a.... Chỉ là một địa chỉ bộ nhớ. Phương thức siêu dữ liệu __tostring cho phép bạn xác định chính xác chuỗi đại diện cho đối tượng khi in hoặc chuyển đổi đối tượng thành văn bản.

Trong mẫu lớp, bạn thêm __tostring làm một hàm trong bảng lớp. Vì bản thân lớp đóng vai trò là metatable cho các instance, Lua sẽ tự động tìm và sử dụng hàm này:

local Player = {}
Player.__index = Player

function Player:new(name, level)
    local instance = {}
    setmetatable(instance, self)
    instance.name = name
    instance.level = level
    return instance
end

function Player:__tostring()
    return "Player: " .. self.name .. " (Level " .. self.level .. ")"
end

Bây giờ, khi bạn in ra một đối tượng Player, Lua sẽ tự động gọi phương thức __tostring của bạn:

local hero = Player:new("Luna", 5)
print(hero)  -- Đầu ra: Player: Luna (Level 5)

Lưu ý rằng __tostring dùng cú pháp dấu hai chấm và nhận self, nhờ đó bạn có thể truy cập mọi dữ liệu của instance. Hàm phải trả về một chuỗi. Bạn có thể định dạng chuỗi theo cách phù hợp với đối tượng của mình, kết hợp các thuộc tính để tạo thành một nội dung dễ đọc.

challenge icon

Thử thách

Dễ

Hãy tạo một lớp (class) Book biết cách tự giới thiệu! Khi bạn in trực tiếp một cuốn sách, Lua sẽ hiển thị một chuỗi được định dạng rõ ràng thay vì một địa chỉ bộ nhớ khó hiểu, tất cả là nhờ metamethod __tostring.

Bạn sẽ sắp xếp code trong hai tệp:

  • Book.lua: Định nghĩa lớp Book theo mẫu prototype tiêu chuẩn. Mỗi cuốn sách cần lưu title và author. Thêm hàm khởi tạo :new(title, author) và triển khai metamethod __tostring để khi in một cuốn sách, thông tin của sách sẽ hiển thị theo định dạng dễ đọc.
  • main.lua: Yêu cầu module Book, tạo các instance sách và in trực tiếp chúng để xem cách định dạng chuỗi tùy chỉnh hoạt động.

Phương thức __tostring cần trả về một chuỗi theo đúng định dạng sau:

"[title]" by [author]

Lưu ý rằng tiêu đề được đặt trong dấu ngoặc kép ở chuỗi đầu ra.

Bạn sẽ nhận được bốn đầu vào:

  1. Tiêu đề của cuốn sách thứ nhất
  2. Tác giả của cuốn sách thứ nhất
  3. Tiêu đề của cuốn sách thứ hai
  4. Tác giả của cuốn sách thứ hai

Trong tệp chính, hãy tạo hai cuốn sách bằng các đầu vào đã cho và in trực tiếp từng cuốn (không gọi phương thức, chỉ dùng print(book)). Mỗi cuốn sách sẽ hiển thị trên một dòng riêng.

Ví dụ, nếu đầu vào là The Hobbit, J.R.R. Tolkien, 1984 và George Orwell, đầu ra sẽ là:

"The Hobbit" by J.R.R. Tolkien
"1984" by George Orwell

Hãy nhớ rằng __tostring phải trả về một chuỗi. Vì bảng lớp của bạn đóng vai trò là metatable cho các instance, Lua sẽ tự động tìm và dùng hàm __tostring khi bạn in một cuốn sách.

Tự làm thử

-- Nạp module Book bằng require
local Book = require('Book')

-- Đọc dữ liệu đầu vào
local title1 = io.read()
local author1 = io.read()
local title2 = io.read()
local author2 = io.read()

-- TODO: Tạo hai instance của Book bằng Book:new()


-- TODO: In trực tiếp từng cuốn sách (chỉ cần dùng print(book))

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 Lập trình hướng đối tượng

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