Lua - Xử lý lỗi
Cần xử lý lỗi
Việc xử lý lỗi là khá quan trọng vì các hoạt động trong thế giới thực thường yêu cầu sử dụng các hoạt động phức tạp, bao gồm hoạt động tệp, giao dịch cơ sở dữ liệu và lệnh gọi dịch vụ web.
Trong bất kỳ lập trình nào, luôn có yêu cầu về xử lý lỗi. Lỗi có thể có hai loại bao gồm,
- Lỗi cú pháp
- Lỗi thời gian chạy
Lỗi cú pháp
Lỗi cú pháp xảy ra do sử dụng không đúng các thành phần chương trình khác nhau như toán tử và biểu thức. Một ví dụ đơn giản cho lỗi cú pháp được hiển thị bên dưới.
a == 2
Như bạn đã biết, có sự khác biệt giữa việc sử dụng đơn "bằng với" và kép "bằng với". Sử dụng cái này thay vì cái kia có thể dẫn đến lỗi. Một "bằng với" đề cập đến sự phân công trong khi một "bằng với" gấp đôi dùng để so sánh. Tương tự, chúng ta có các biểu thức và hàm có các cách thực hiện được xác định trước.
Một ví dụ khác cho lỗi cú pháp được hiển thị bên dưới:
for a= 1,10
print(a)
end
Khi chúng tôi chạy chương trình trên, chúng tôi sẽ nhận được kết quả sau:
lua: test2.lua:2: 'do' expected near 'print'
Lỗi cú pháp dễ xử lý hơn nhiều so với lỗi thời gian chạy vì trình thông dịch Lua định vị lỗi rõ ràng hơn so với trường hợp lỗi thời gian chạy. Từ lỗi trên, chúng ta có thể biết một cách dễ dàng rằng việc thêm một việc phải làm tuyên bố trước khi tuyên bố in được yêu cầu theo cấu trúc Lua.
Lỗi thời gian chạy
Trong trường hợp lỗi thời gian chạy, chương trình thực thi thành công, nhưng nó có thể dẫn đến lỗi thời gian chạy do lỗi nhập hoặc xử lý sai các chức năng. Dưới đây là một ví dụ đơn giản để hiển thị lỗi thời gian chạy.
function add(a,b)
return a+b
end
add(10)
Khi chúng tôi xây dựng chương trình, nó sẽ xây dựng thành công và chạy. Khi nó chạy, hiển thị lỗi thời gian chạy.
lua: test2.lua:2: attempt to perform arithmetic on local 'b' (a nil value)
stack traceback:
test2.lua:2: in function 'add'
test2.lua:5: in main chunk
[C]: ?
Đây là lỗi thời gian chạy, đã xảy ra do không chuyển hai biến. Cácb tham số được mong đợi và ở đây nó là nil và tạo ra lỗi.
Chức năng Khẳng định và Lỗi
Để xử lý lỗi, chúng tôi thường sử dụng hai hàm: assert và error. Một ví dụ đơn giản được hiển thị bên dưới.
local function add(a,b)
assert(type(a) == "number", "a is not a number")
assert(type(b) == "number", "b is not a number")
return a+b
end
add(10)
Khi chúng tôi chạy chương trình trên, chúng tôi sẽ nhận được đầu ra lỗi sau.
lua: test2.lua:3: b is not a number
stack traceback:
[C]: in function 'assert'
test2.lua:3: in function 'add'
test2.lua:6: in main chunk
[C]: ?
Các error (message [, level])chấm dứt chức năng được bảo vệ cuối cùng được gọi và trả về thông báo dưới dạng thông báo lỗi. Lỗi hàm này không bao giờ trả về. Thông thường, lỗi thêm một số thông tin về vị trí lỗi ở đầu thư. Đối số mức chỉ định cách lấy vị trí lỗi. Với mức 1 (mặc định), vị trí lỗi là nơi hàm lỗi được gọi. Mức 2 chỉ lỗi đến nơi mà hàm được gọi là lỗi đã được gọi; và như thế. Vượt qua mức 0 sẽ tránh được việc bổ sung thông tin vị trí lỗi vào thông báo.
pcall và xpcall
Trong lập trình Lua, để tránh ném ra các lỗi này và xử lý lỗi, chúng ta cần sử dụng các hàm pcall hoặc xpcall.
Các pcall (f, arg1, ...)hàm gọi hàm được yêu cầu ở chế độ được bảo vệ. Nếu một số lỗi xảy ra trong hàm f, nó không tạo ra lỗi. Nó chỉ trả về trạng thái lỗi. Dưới đây là một ví dụ đơn giản sử dụng pcall.
function myfunction ()
n = n/nil
end
if pcall(myfunction) then
print("Success")
else
print("Failure")
end
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.
Failure
Các xpcall (f, err)hàm gọi hàm được yêu cầu và cũng đặt trình xử lý lỗi. Bất kỳ lỗi nào bên trong f không được lan truyền; thay vào đó, xpcall bắt lỗi, gọi hàm err với đối tượng lỗi ban đầu và trả về mã trạng thái.
Một ví dụ đơn giản cho xpcall được hiển thị bên dưới.
function myfunction ()
n = n/nil
end
function myerrorhandler( err )
print( "ERROR:", err )
end
status = xpcall( myfunction, myerrorhandler )
print( status)
Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.
ERROR: test2.lua:2: attempt to perform arithmetic on global 'n' (a nil value)
false
Là một lập trình viên, điều quan trọng nhất là đảm bảo rằng bạn quan tâm đến việc xử lý lỗi thích hợp trong các chương trình bạn viết. Sử dụng xử lý lỗi có thể đảm bảo rằng các điều kiện bất ngờ ngoài điều kiện biên được xử lý mà không làm phiền người dùng chương trình.