从返回多个值的 lua 函数返回错误的最佳实践

发布于 2024-12-25 08:10:26 字数 760 浏览 1 评论 0原文

我有一个 lua 函数,它接受多个参数并返回与参数一样多的值。每个返回值对应一个参数。为了说明这一点,请考虑一个从数据库读取键/值对值的函数:

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

my_function 返回错误的最佳方式是什么?(例如,如果提供的“key”无效)

我知道一种方法是在错误时返回两个值,nil 和一个错误字符串。这是最好的方法吗?例如:

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

编辑

一些附加要点:

  1. lua 脚本是使用 lua_pcall() 从 C 程序中执行的。
  2. 如果脚本失败,C 程序不得中止。
  3. my_function() 是用 C 实现的。
  4. my_function() 失败时,它还应该返回一个错误代码(或消息),指示失败的原因。

I have a lua function which takes multiple parameters and returns as many values as there are parameters. Each return value corresponds to a parameter. To illustrate, consider a function which reads the value for a key/value pair from a database:

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

What is the best way to return an error from my_function? (e.g. if a supplied "key" is invalid)

I understand one way is to return two values on error, nil and an error string. Is this the best approach? For example:

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

Edit

Some additional points:

  1. The lua script is being executed from within a C program using lua_pcall().
  2. The C program must not abort if the script fails.
  3. my_function() is implemented in C.
  4. When my_function() fails, it should also return an error code (or message) indicating the reason it failed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不寐倦长更 2025-01-01 08:10:26

Lua 中抛出错误的标准方法是通过错误函数(手册api)或通过 断言(内部无论如何都会使用error)。

由于您的函数是用 C 语言编写的,因此您应该在其中调用 lua_error 以获得相同的效果。

但请记住,您现在的功能是“不安全的”。如果未修改,如果 key1、key2 或 key3 “错误”,以下代码将执行相当于“抛出异常”的操作,从而停止程序:

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

有时,如果输入错误,让程序“崩溃”也是可以的。根据您的设置,用户将收到一条消息,其中包含最后一个错误、堆栈跟踪或类似的内容。

如果“让程序崩溃”不是一个选项,您可以使用 pcall 函数,并添加一个名为 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

请注意,您不必将 pcall 完全放在my_function 的顶部。与异常一样,错误恢复可能发生在调用链的较高位置:在调用 my_function 的函数中,或在调用该函数的函数中,等等。例如,如果您调用 my_function > 来自一个名为 parent 的函数,以及来自一个名为 grandParent 的函数,您可以执行以下操作:

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

The standard way of throwing errors in Lua is via the error function (manual, api) or via assert (which internally uses error anyway).

Since your function is in C, you should be calling lua_error inside it, to gain the same effect.

But keep in mind that your function now is "insecure". If unmodified, the following code will do the equivalent of "throwing an exception" and thus halting the program, if key1, key2 or key3 are "erroneous":

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

Sometimes it's ok to let the program "just crash" if the inputs are wrong. Depending on your setup, the user will get a message with the last error, and a stack trace, or something along those lines.

If "letting the program crash" is not an option, you can do the equivalent of surrounding it with a "try-catch" block by using the pcall function, and adding a new variable called 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

Notice that you don't have to put pcall exactly on top of my_function. As with exceptions, the error recuperation can happen higher in the call chain: in the function calling my_function, or the function calling that one, etc. For example, if you call my_function from a function called parent, and parent from one called grandParent, you can do this:

-- 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
哥,最终变帅啦 2025-01-01 08:10:26

通常的做法是在程序无法恢复时抛出错误(例如错误的文件句柄),并在程序可以恢复时发出错误信号(例如找不到文件)。就您而言,我认为简单地为无效键返回 nil 是最好的方法。

The usual practice is to throw errors when the program cannot recover (bad file handle for instance) and signal errors when it can recover (file not found for instance). In your case, I think that simply returning nil for invalid keys is the best way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文