Menu
CoddyTech

Lời gọi an toàn với pcall()

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 33 trên 54.

Trong khi error() dừng chương trình khi có sự cố, đôi khi bạn muốn xử lý lỗi mà không làm chương trình bị dừng đột ngột. Hàm pcall() của Lua cho phép bạn chạy an toàn đoạn code có thể gặp lỗi.

Tên pcall() có nghĩa là “lời gọi được bảo vệ”. Nó bọc lời gọi hàm trong một lớp bảo vệ để bắt mọi lỗi. Thay vì chương trình bị dừng, pcall() trả về thông tin về những gì đã xảy ra.

Đây là cú pháp cơ bản:

local status, result = pcall(functionName, arg1, arg2)

Hàm (function) pcall() trả về hai giá trị. Giá trị đầu tiên là trạng thái boolean: true nếu hàm chạy thành công, hoặc false nếu xảy ra lỗi. Giá trị thứ hai tùy thuộc vào trạng thái: nếu thành công, đó là giá trị trả về của hàm; nếu xảy ra lỗi, đó là thông báo lỗi.

Đây là một ví dụ thực tế:

function divide(a, b)
    if b == 0 then
        error("Cannot divide by zero")
    end
    return a / b
end
local success, result = pcall(divide, 10, 0)
if success then
    print("Result: " .. result)
else
    print("Error caught: " .. result)
end

Trong ví dụ này, phép chia cho 0 gây ra lỗi, nhưng thay vì bị dừng đột ngột, pcall() bắt lỗi đó. Chương trình tiếp tục chạy và có thể xử lý lỗi một cách phù hợp bằng cách kiểm tra giá trị trạng thái.

challenge icon

Thử thách

Dễ

Viết một hàm (function) safeCalculate nhận operation, a và b, rồi trả về kết quả phép tính hoặc thông báo lỗi.

Hàm này cần dùng pcall() để thực hiện phép toán được yêu cầu một cách an toàn. Tạo một hàm bên trong để tính toán dựa trên chuỗi thao tác, sau đó bọc hàm đó bằng pcall() để bắt lỗi.

Logic:

  • Tạo một hàm bên trong để kiểm tra loại thao tác và thực hiện phép tính
  • Với "add", trả về a + b
  • Với "subtract", trả về a - b
  • Với "multiply", trả về a * b
  • Với "divide", kiểm tra xem b có bằng 0 không. Nếu đúng, gọi error("Division by zero", 0), nếu không thì trả về a / b
  • Với mọi thao tác khác, gọi error("Invalid operation", 0)
  • Dùng pcall() để thực thi hàm bên trong
  • Nếu thành công, trả về "Result: " theo sau là kết quả
  • Nếu xảy ra lỗi, trả về "Error: " theo sau là thông báo lỗi

Truyền 0 làm đối số thứ hai của error(). Đối số đó là cấp độ lỗi, và 0 yêu cầu Lua không thêm tên tệp và số dòng vào trước thông báo của bạn, vì vậy chuỗi được trả về sẽ chính xác là "Error: Division by zero".

Tham số:

  • operation (chuỗi): Thao tác cần thực hiện ("add", "subtract", "multiply" hoặc "divide")
  • a (số): Toán hạng thứ nhất
  • b (số): Toán hạng thứ hai

Giá trị trả về: Một chuỗi chứa "Result: " theo sau là kết quả phép tính, hoặc "Error: " theo sau là thông báo lỗi (chuỗi)

Tự làm thử

function safeCalculate(operation, a, b)
    -- Viết code ở đây
    -- Lưu ý: gọi error(message, 0) để Lua không thêm tên tệp và
    -- số dòng vào trước thông báo của bạn.
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