2012-01-06 73 views
6

Tôi có hàm lua có nhiều tham số và trả về nhiều giá trị khi có tham số. Mỗi giá trị trả lại tương ứng với tham số. Để minh họa, hãy xem xét một chức năng mà đọc giá trị cho một cặp khóa/giá trị từ một cơ sở dữ liệu:Thực hành tốt nhất để trả về lỗi từ hàm lua trả về nhiều giá trị

val1, val2, val3 = my_function("key1", "key2", "key3"); 
val1 = my_function("key1"); 

cách tốt nhất để trả lại một lỗi từ my_function là gì? (ví dụ: nếu "khóa" được cung cấp không hợp lệ)

Tôi hiểu một cách là trả về hai giá trị do lỗi, nil và chuỗi lỗi. Đây có phải là cách tiếp cận tốt nhất không? Ví dụ:

val1, val2, val3 = my_function("key1", "key2", "key3"); 
if val1 then 
    -- Use val1, val2, and val3. 
else 
    print("ERROR: " .. val2); 
end 

Sửa

Một số điểm bổ sung:

  1. Kịch bản lua đang được thực hiện từ bên trong một chương trình C sử dụng lua_pcall().
  2. Chương trình C không được hủy nếu tập lệnh không thành công.
  3. my_function() được triển khai trong C.
  4. Khi my_function() không thành công, nó cũng phải trả về mã lỗi (hoặc thông báo) cho biết lý do không thành công.

Trả lời

6

Cách chuẩn ném sai sót trong Lua là thông qua các hàm lỗi (manual, api) hoặc qua assert (mà trong nội bộ sử dụng error anyway).

Vì chức năng của bạn ở trong C, bạn nên gọi số lua_error bên trong nó, để đạt được hiệu quả tương tự.

Nhưng hãy nhớ rằng chức năng của bạn bây giờ là "không an toàn". Nếu chưa sửa đổi, đoạn code sau sẽ làm tương đương với "ném một ngoại lệ" và do đó ngăn chặn các chương trình, nếu key1, key2 hoặc key3 là "sai lầm":

val1, val2, val3 = my_function("key1", "key2", "key3") 

Đôi khi nó là ok để cho chương trình "chỉ sụp đổ "nếu đầu vào sai. Tùy thuộc vào thiết lập của bạn, người dùng sẽ nhận được thông báo có lỗi cuối cùng và theo dõi ngăn xếp hoặc thứ gì đó dọc theo các dòng đó.

Nếu "để cho sự sụp đổ của chương trình" không phải là một lựa chọn, bạn có thể làm tương đương với xung quanh nó với một "try-catch" khối bằng công pcall chức năng, và thêm một biến mới gọi là ok:

ok, val1, val2, val3 = pcall(my_function, "key1", "key2", "key3") 
if ok then 
    -- Use val1, val2, and val3. 
else 
    print("ERROR: " .. val1) -- notice that we use val1 here, not val2 
end 

Lưu ý rằng bạn không phải đặt pcall chính xác ở trên cùng của my_function. Cũng như các trường hợp ngoại lệ, lỗi phục hồi có thể xảy ra cao hơn trong chuỗi cuộc gọi: trong hàm gọi my_function hoặc chức năng gọi hàm đó, v.v.Ví dụ, nếu bạn gọi my_function từ một chức năng gọi là parent, và phụ huynh từ một gọi grandParent, bạn có thể làm điều này:

-- parent is "insecure" since my_function is "unprotected" 
function parent(key1, key2) 
    local val1, val2, val3 = my_function(key1, key2, "key3") 
    return val1, val2, val3 
end 

-- grandParent calls parent in a "safe" way 
function grandParent() 
    local ok, val1, val2, val3 = pcall(parent, "key1", "key2") 
    if ok then 
    -- Use val1, val2, and val3. 
    else 
    print("ERROR: " .. val1) 
    end 
end 
+0

Tôi đã chỉnh sửa câu hỏi để làm rõ một vài điểm. Vì kịch bản lệnh lua (mà cuối cùng gọi 'my_function()') được chạy từ C với 'lua_pcall()', nên 'my_function()' trả về biến "ok" như bạn đã mô tả ở trên? (ví dụ: 'ok, val1, val2, val3 = my_function()'). – Ben

+0

@Ben, vâng, tôi sẽ bao gồm một giá trị 'ok' bổ sung - có vẻ là cách sạch nhất. Tôi cũng khuyên bạn nên sửa đổi trong thiết kế; kể từ khi cả hai chức năng trong C, nó có thể sẽ được đơn giản hơn (và nhanh hơn) để quên về Lua và chỉ làm tất cả mọi thứ trong C. – kikito

+0

@ kikto, nhờ làm rõ. Trong trường hợp này, nó có ý nghĩa đối với tôi khi sử dụng lua (hoặc tương đương) để mở rộng sản phẩm. – Ben

0

Việc thực hành thông thường là để ném lỗi khi chương trình không thể phục hồi (xử lý tập tin xấu ví dụ) và tín hiệu lỗi khi nó có thể phục hồi (tập tin không tìm thấy ví dụ). Trong trường hợp của bạn, tôi nghĩ rằng chỉ cần trả lại nil cho các khóa không hợp lệ là cách tốt nhất.

+0

Nếu tôi muốn my_function() cũng trả lại lý do nó không thành công, bạn có ủng hộ rằng nếu 'val1, val2, val3 = my_function()' không thành công, 'val1' phải là' nil' và 'val2' phải là mã lỗi /thông điệp? – Ben

+0

@Ben, không, tôi nghĩ lý do duy nhất là "khóa không hợp lệ". – lhf

Các vấn đề liên quan