动态定义LUA函数的正确方法
2019-7-29 14:6:59
收藏:0
阅读:150
评论:2
我最近一周一直在使用Lua,最终编写了这段代码。我发现可以动态创建新函数并从其他函数“继承”,所以程序员必须给它命名。我的问题是:
这被称为什么?
是否有更好的方法来完成此任务?(循环遍历数据结构并创建“改进”现有函数的插件函数)
D = {
name = {
value = nil,
offset = 0,
update = function (self)
self.value = "Berlin"
end,
},
}
--动态函数定义
for i in pairs(D) do
D[i].upAndWrite = function(self)
self:update()
print("upAndWrite was here")
end
end
print(D.name.value)
D.name:upAndWrite()
print(D.name.value)
结果:
nil
upAndWrite was here
Berlin
原文链接 https://stackoverflow.com/questions/57255454
点赞
stackoverflow用户4984564
作为一个整体,它没有一个名称。有很多概念参与其中:
- 头等函数,也称为可以分配给变量并像数字或字符串一样传递的函数。
- 匿名函数,也称为没有明确给它命名的函数。Lua 中的所有函数都是_技术上_匿名的,但通常它们在创建后立即分配到一个变量中。
- 元编程,即编写编写程序的程序。创建函数(或方法)的循环在任意数量的对象上是非常简单的,但我会将它视为元编程。
- Lua 表;这似乎是显而易见的,但请考虑并非所有语言都具有这样的功能。Javascript 有_对象_类似,但例如 Ruby 没有可比较的功能。
如果你要使用 pairs
,你可能也要利用两个变量。
for key, object in pairs(D) do
function object:upAndWrite(self)
self:update()
print("upAndWrite was here")
end
end
虽然这会创建许多闭包,这意味着垃圾收集器会更加繁重,内存使用量和执行速度会更慢。
for key, object in pairs(D) do
print(object.upAndWrite) -- 所有的函数都不同
end
这是一个不错的第一阶段,但在重构一下之后,你可以得到这个:
do
local method = function(self) -- 仅创建一个闭包
self:update()
print("upAndWrite was here")
end
for key, object in pairs(D) do
object.upAndWrite = method -- 多次使用一个闭包
end
end
现在只有一个闭包被所有表共享。
for key, object in pairs(D) do
print(object.upAndWrite) -- 所有的函数都是相同的
end
2019-07-30 06:12:03
评论区的留言会收到邮件通知哦~
推荐文章
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
我认为你所做的没有特别的名称,只是即时创建函数。
关于你的代码,有几个要注意的地方:
正确的循环
for i in pairs(D) do ... end
在编程中,变量
i
通常用于计数循环,例如:for i=1,100 do ... end
在这里,
pairs
返回一个迭代器函数,并且惯用的用法是for k,v in pairs(D) do ... end
这里,
k
是键(类似于你的代码中的i
),而v
是值(当你需要访问对应值时,请使用它而不是像D[k]
或D[i]
这样的表索引)。没有必要即时创建函数!
另一件重要的事情是,你在每个循环迭代中创建了新函数。虽然这个特性非常强大,但是你根本没有使用它,因为你没有使用upvalues存储任何东西,并且仅通过参数访问数据。
更好的方法是创建一个函数并将其分配给每个字段:
--在这里定义D do local function upAndWrite(self) self:update() print("upAndWrite was here") end for k,v in pairs(D) do v.upAndWrite = upAndWrite --使用我们的函数 end end --在这里执行测试
即时创建函数允许做什么?
如上所述,您可以在某些情况下利用这个非常强大的闭包机制。这里是一个简单的例子:
local t = {} for i = 1, 100 do --创建函数以打印我们的值 t[i] = function() print(i) end --创建将值增加一的函数 t[-i] = function() i=i+1 end end t[1]() --打印1 t[20]() --打印20 t[-20]() --将upvalue增加1 t[20]() --现在是21!
这个例子演示了upvalues的一个可能用法,以及许多函数可以共享它们的事实。这可以与事实一起在多种情况下使用,即upvalues不能被旁白代码更改(不使用
debug
库),并且通常是可信的。希望我的回答可以覆盖你想知道的内容。
注意:此外,这种语言称为[Lua而不是LUA](https://www.lua.org/about.html#name)。