Lua &引用;尝试索引本地…“;为什么我会犯这个错误?

Lua &引用;尝试索引本地…“;为什么我会犯这个错误?,lua,coronasdk,Lua,Coronasdk,我是Lua的新手,我想在脑子里把事情整理一下。我尝试了以下代码: function newCarousel(images) local slideToImage = function() print("ah!") end end local testSlide = newCarousel(myImages) testSlide.slideToImage() 这给了我这个错误: 尝试索引本地“testSlide”(一个nil值) 这是为什么?因为newCa

我是Lua的新手,我想在脑子里把事情整理一下。我尝试了以下代码:

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


local testSlide = newCarousel(myImages)
testSlide.slideToImage()
这给了我这个错误:

尝试索引本地“testSlide”(一个nil值)


这是为什么?

因为
newCarousel
不返回任何内容,所以
testSlide
为零,所以当您尝试对其进行索引时(
testSlide.slideToImage
testSlide[“slideToImage”]
)会出现错误


我建议你读书。您可以通过反复试验来确定该语言的语法、语义和习惯用法,但这将花费您更长的时间。

您现在得到的代码不会返回任何内容。(这不是Scheme或Ruby之类,最后一个表达式是返回值。)此外,您似乎认为
newCarousel
是一个对象。事实并非如此。这是一个函数。当您完成呼叫
newCarousel
时,一切都结束了。它完成了它的工作,不管是什么(在您的例子中,它创建了一个局部变量,该变量被迅速删除并返回
nil

正确的代码更像:

function newCarousel(images) 
    return function() 
        print("ah!")
    end
end

local testSlide = newCarousel(myImages)
testSlide()
现在我创建了一个(匿名)函数并立即返回它。这个匿名函数绑定到
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
main(8条指令,0xeb6540处32字节)
0+参数,2个插槽,0个上限值,1个本地,3个常量,1个函数
1[5]闭包0;0xeb6720
2[1]设置全局0-1;纽卡鲁塞尔
3[7]GETGLOBAL 0-1;纽卡鲁塞尔
4[7]GETGLOBAL 1-2;我的图像
5[7]呼叫0 2 2
6[8]可获取10-3;“幻灯片图像”
7[8]拨打1
8[8]返回0 1
函数(2条指令,0xeb6720处8个字节)
1个参数,2个插槽,0个上限值,2个局部变量,0个常量,1个函数
1[4]关闭1 0;0xeb6980
2[5]返回0 1
函数(4条指令,0xeb6980处16字节)
0个参数,2个插槽,0个上限值,0个局部变量,2个常量,0个函数
1[3]获取全局0-1;打印
2[3]荷载K 1-2;“啊!”
3[3]呼叫0 2 1
4[4]返回0 1

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

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

function newCarousel(images)
    local t = {}
    t.slideToImage = function() 
        print("ah!")
    end
    return t
end
您甚至可以构建t并在一个步骤中返回它;以下代码等同于上述代码:

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

谢谢你提供的信息。我会接受你的回答,但@egarcia解决了我的问题。我同意Mud的建议阅读。虽然学习该语言的基础知识并使某些东西正常工作很容易,但Lua有一些非常强大的功能,除非您阅读了文档,否则这些功能并不明显。@Elliot:我很想这么做。请注意,当egarcia说“最简单的解决方案”时,他指的是最简单的事情,可以让您的坏代码正常工作,但在您的代码的更大上下文中(
newCarousel
正在创建一个对象,
slideToImage
是一种方法),这不是解决问题的正确方法。您真正需要的是包含旋转木马方法的元表,以及将其应用于新对象的
new
方法。但是,要让您了解该解决方案,需要在这里复制Lua中的大部分编程,所以我建议您阅读它。我理解并感谢您的理解。我一定会检查它,我可能会参考它很多,但目前,我只是试图解决一个特定的问题。我对你的问题投了赞成票,但接受了egarcia的回答,因为那正是我想要的。