Lua &引用;尝试索引本地…“;为什么我会犯这个错误?
我是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
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的回答,因为那正是我想要的。