【问题标题】:Error with self invoking anonymous functions in Lua在 Lua 中自我调用匿名函数时出错
【发布时间】:2020-09-13 18:06:47
【问题描述】:

我正在尝试在 Lua 中使用自调用匿名函数,但看到了一些奇怪的行为。

这个:

(function ()
  print("self-invoking approach")
end)()

print("standard approach")

工作正常并打印以下输出:

self-invoking approach
standard approach

但将两者颠倒:

print("standard approach")

(function ()
  print("self-invoking approach")
end)()

导致此错误:

➜  hammerspoon   lua temp.lua
standard approach
lua: temp.lua:1: attempt to call a nil value
stack traceback:
    temp.lua:1: in main chunk
    [C]: in ?

奇怪的是,在 Lua REPL 中运行代码时,只有在函数形式为 second 的情况下才会发生故障,并且两个调用都包装在一个被调用的外部函数中:

function foo()
    print("standard approach")

    (function ()
      print("self-invoking approach")
    end)()
end

foo()

这里发生了什么?

【问题讨论】:

    标签: function lambda lua interpreter


    【解决方案1】:

    这是一个解析歧义。非工作案例被解析为:

    print("standard approach")(function ()
      print("self-invoking approach")
    end)()
    

    换句话说,它打印standard approach,然后获取print(即nil)的返回值,并尝试使用您的自调用函数作为参数调用它(之后它将如果它还没有崩溃,也试图调用它的结果)。要修复它,请在第一个 print 函数调用的末尾添加一个分号。

    【讨论】:

    • 这不是模棱两可的。解析器采用最长的有效表达式。
    • @lhf 不是吗?我认为这是一种歧义,采用最长的有效表达式是它选择解决歧义的方式。
    • 另外,在 Lua 5.1 中,它确实无法解析并出现错误 ambiguous syntax (function call x new statement)
    • 哇!我很惊讶。其他语言有这种行为吗?我不认为我以前见过它。我决定把“;”直接在函数定义 (;(function...) 之前,以确保它永远不会被视为先前语句的一部分。
    • 在 javascript 中试试这个:console.log("test") ( () => console.log("foo"))() 同样的问题,同样的解决方案(添加 ;)。发生这种情况是因为括号在许多编程语言中用于不止一件事,这可能导致这些歧义。
    猜你喜欢
    • 2011-12-29
    • 2013-02-23
    • 2014-09-11
    • 1970-01-01
    • 1970-01-01
    • 2019-12-30
    • 2012-06-28
    • 2012-03-17
    相关资源
    最近更新 更多