【问题标题】:"Attempt to index local..." Why am I getting this error?“尝试索引本地...”为什么会出现此错误?
【发布时间】:2011-05-19 05:06:48
【问题描述】:

我是 Lua 的新手,并试图在我的脑海中整理好东西。我试过这段代码:

function newCarousel(images) 
    local slideToImage = function() 
        print("ah!")
    end
end


local testSlide = newCarousel(myImages)
testSlide.slideToImage()

这给了我这个错误:

尝试索引本地“testSlide”(零值)...

这是为什么?

【问题讨论】:

    标签: lua coronasdk


    【解决方案1】:

    因为newCarousel 什么都不返回,所以testSlide 为零,所以当你尝试索引它时(testSlide.slideToImage 完全等同于testSlide["slideToImage"])你会得到一个错误。

    我建议阅读Programming in Lua。您也许可以通过反复试验来弄清楚该语言的语法、语义和习语,但这会花费您更长的时间。

    【讨论】:

    • 感谢您的信息。我会接受你的回答,但@egarcia 解决了我的问题。
    • 我支持 Mud 的推荐阅读 Programming in Lua。虽然学习该语言的基础知识并让一些东西工作起来很容易,但 Lua 有一些非常强大的功能,除非您阅读过文档,否则这些功能并不明显。
    • @Elliot:我很想这样做。请注意,当 egarcia 说“最简单的解决方案”时,他的意思是让您损坏的代码正常工作的最简单的事情,但在代码的更大上下文中(newCarousel 正在创建一个对象,slideToImage 是一种方法)这是 不是解决您的问题的正确方法。您真正想要的是一个包含 Carousel 方法的元表,以及一个将其应用于新对象的 new 方法。但是,为您提供必要的背景知识来理解该解决方案需要在此处复制大部分 Lua 编程,所以我建议您阅读它。
    • 我理解并感谢它。我一定会检查它,我可能会引用它很多,但目前,我只是试图解决一个特定的问题。我赞成你的问题,但接受了 egarcia 的回答,因为这正是我想要的。
    【解决方案2】:

    如果您希望能够做到testSlide.slideToImage(),您必须修改newCarousel,以便它返回一个包含函数的表。最简单的实现如下:

    function newCarousel(images)
        local t = {}
        t.slideToImage = function() 
            print("ah!")
        end
        return t
    end
    

    您甚至可以一步构建并返回它;下面的代码和上面的代码是等价的:

    function newCarousel(images)
        return {
            slideToImage = function() 
                print("ah!")
            end
        }
    end
    

    【讨论】:

      【解决方案3】:

      你现在得到的代码,如Mud stated,不会返回任何东西。 (这不是最后一个表达式是返回值的 Scheme 或 Ruby 等。)此外,您似乎认为 newCarousel 是一个对象。它不是。这是一个功能。当你打完newCarousel 就结束了。它已经完成了它的工作,不管它是什么(在你的情况下,它是创建一个立即删除并返回 nil 的局部变量)。

      正确的代码看起来更像:

      function newCarousel(images) 
          return function() 
              print("ah!")
          end
      end
      
      local testSlide = newCarousel(myImages)
      testSlide()
      

      我现在有newCarousel 创建一个(匿名)函数并立即返回它。这个匿名函数绑定到testSlide,所以只要testSlide 在范围内,我就可以随时调用它。


      在玩 Lua 时查看生成的代码很有启发性。首先让我们看看luac 为您的代码生成了什么:

      main <junk.lua:0,0> (8 instructions, 32 bytes at 0xeb6540)
      0+ params, 2 slots, 0 upvalues, 1 local, 3 constants, 1 function
          1   [5] CLOSURE     0 0 ; 0xeb6720
          2   [1] SETGLOBAL   0 -1    ; newCarousel
          3   [7] GETGLOBAL   0 -1    ; newCarousel
          4   [7] GETGLOBAL   1 -2    ; myImages
          5   [7] CALL        0 2 2
          6   [8] GETTABLE    1 0 -3  ; "slideToImage"
          7   [8] CALL        1 1 1
          8   [8] RETURN      0 1
      
      function <junk.lua:1,5> (2 instructions, 8 bytes at 0xeb6720)
      1 param, 2 slots, 0 upvalues, 2 locals, 0 constants, 1 function
          1   [4] CLOSURE     1 0 ; 0xeb6980
          2   [5] RETURN      0 1
      
      function <junk.lua:2,4> (4 instructions, 16 bytes at 0xeb6980)
      0 params, 2 slots, 0 upvalues, 0 locals, 2 constants, 0 functions
          1   [3] GETGLOBAL   0 -1    ; print
          2   [3] LOADK       1 -2    ; "ah!"
          3   [3] CALL        0 2 1
          4   [4] RETURN      0 1
      

      在您的代码中,主线创建了一个闭包,将其绑定到名称 newCarousel,获取该值,获取 myImages 的值并进行调用。这对应于local testSlide = newCarousel(myImages)。接下来,它从本地表 (testSlide) 中获取 slideToImage 值。这里的问题是testSlide 不是表,而是nil。这是您的错误消息的来源。请注意,这不是唯一的错误,但它是运行时看到的第一个错误,也是导致一切阻塞的原因。如果你从newCarousel 返回了一个实际的函数,你会得到一个不同的错误。例如,如果我将行 return slideToImage 添加到 newCarousel 函数,则错误消息将是“尝试索引本地 'testSlide'(函数值)”。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-03-07
        • 1970-01-01
        • 2012-03-09
        • 1970-01-01
        • 1970-01-01
        • 2013-08-14
        • 2020-10-18
        相关资源
        最近更新 更多