【问题标题】:In Lua, how to set a nil parameter to some default value correctly?在 Lua 中,如何正确地将 nil 参数设置为某个默认值?
【发布时间】:2015-05-25 05:14:28
【问题描述】:

下面的 Lua 代码:

local function foo(x, y, z)
    local x = x or true
    local y = y or 1234
    z = z or "default"
end

我一直以为函数里面这三行的意思是:

如果 x/y/z 为 nil,则 x/y/z 设置为 true/1234/"default"。否则,无论它是什么,它都保持不变。因此,我在很多地方都有这样一行来将参数设置为某个默认值,以防它可能作为 nil 传递给函数。

但是,在我的实验中似乎并不完全正确。我不确定我在哪里学到了这个 Lua 编码概念。如何正确操作?

【问题讨论】:

  • 如果我将false作为第一个参数传递就会失败
  • 风格是不要把local放在前面。 (这实际上创建了一个新变量。您可以在某些调试器中看到它。)

标签: function parameters lua


【解决方案1】:

只要您的布尔(?) 变量x 未被初始化为false,该方法就会起作用。如果你只想对nil 值使用默认值,a or b 方法是正确的。

如果您的变量可以是 false,则必须使用严格的 if-then 块:

if x == nil then x = true end

您可以在lua wiki 上看到更多关于三元运算符的方法/示例。

【讨论】:

  • 是的,这是我发现的一件事,如果传入的变量为假,它就会变为真,而不是保持假。这就是为什么我开始担心使用这样的语句。那么,这是唯一的情况吗?即使是这样,我最好开始使用严格的 if-then 以避免任何混淆。
  • @Joe 请参阅 Lua 手册中的条件。 falsenil 是假的;所有其他值都是真实的。
  • @hjpotter92:更准确地说,'or' 方法适用于所有情况,无论传入的值是 nil、true、false 还是其他任何值,除了默认值该功能必须为真。但是,如果默认值必须为 false,'or' 仍然会起作用(针对 nil),因为 nil 或 false 为 false,而不是 nil。
  • @tonypdmtr 如果我将函数称为foo(false, 3) 我希望我的x 在这里成为falsez; otoh 可以是默认值
  • @hjpotter92 也许你误读了我说的:“除非函数中的默认值必须为真”,就是这种情况。我只是试图更清楚地表明,重要的不是调用者的值,而是函数中所需的默认值。如果我们需要一个 false 默认值,那么使用 nil 或 false 调用都会给我们 false,对吗?
【解决方案2】:

如果您希望能够将nil 作为参数传递(例如,您想区分foo(1,2,nil)foo(1,2)),还有一种更严格的方法

function foo(...)
  local n,x,y,z = select('#', ...), ...
  if n < 3 then z = default end
  if n < 2 then y = default end
  if n < 1 then x = default end
  -- here x,y or z  can be nil
  ...
end

但您必须确保自己知道自己在做什么,因为这可能不是您的功能用户所期望的行为。

【讨论】:

    【解决方案3】:

    这应该可以按预期工作:

    function foo(x, y, z)
        x = (x == nil) or x
        y = (y == nil and 1234) or y
        z = (z == nil and "default") or z
        print(x, y, z)
    end
    
    > foo()
    true    1234    default
    > foo(false, false, "me")
    false   false   me
    > foo(nil, 50, "me")
    true    50  me
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-11
      • 1970-01-01
      • 2017-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-14
      相关资源
      最近更新 更多