将字符串转换为Lua函数。
2012-7-8 3:8:28
收藏:0
阅读:243
评论:3
我正在Lua中从字符串创建函数(of x) 。我使用的代码是
function fcreate(fs)
return assert(loadstring("return function (x) return " .. fs.." end"))()
end
这适用于全局变量,例如
u=fcreate("math.sin(x)")
完成正确的操作。
但是,它似乎不喜欢局部变量。 所以
local c=1
u=fcreate("math.sin(x)+c")
将无法工作,因为c是本地变量。
这可以解决吗?
点赞
用户5696
无论如何都无法合理地完成。为了说明这一点,请看以下代码:
function makefunction(name)
local a = 1
local b = 2
local c = 3
-- ...
return assert(loadstring("return " .. name))
end
local a = 4
local func = makefunction("a")
print(func())
如果这段代码运行成功了,那么会打印出什么?是1还是4?它是否可以捕捉到从已经不存在的函数所在地方中的变量?
如果打印出了1,那么这个函数是按词法作用域创建的。这意味着在函数退出后仍然可以访问变量,这就需要将变量动态提升为一个上值,这是 Lua 目前无法做到的。目前,Lua 在编译过程中可以看到每个对局部变量的访问,因此它知道将哪些变量转化为上值(会影响性能),哪些变量保留为本地变量。
如果打印出了4,那么在loadstring函数中的变量访问与 Lua 中的其他访问是完全不同的。Lua 使用的是词法作用域,而不是动态作用域。这将是 Lua 的一次巨大的实现变更,并且是极其不一致的。
因此,两种做法都不被支持。你可以使用setfenv(Lua 5.1)或 load(...)中的env参数(Lua 5.2) 控制动态加载函数的环境,但这两个方法都不能自动访问局部变量。
2012-07-08 05:55:12
用户90511
如果你不需要改变本地变量,你可以将这些值作为参数传递给生成的函数。虽然你仍然需要手动指定要关闭的变量,但这比没有好。
例如,你可以构建一个闭包如下:
return (function(a,b,c)
return function(x) return print(a, x) end
end)(...)
我们可以通过改变你的函数来实现这个目的:
function fcreate(variables, fs)
local varnames = {}
local varvalues = {}
local nvars = 0
for n,v in pairs(variables) do
nvars = nvars + 1
table.insert(varnames, n)
table.insert(varvalues, v)
end
local chunk_str = (
'return (function(' .. table.concat(varnames, ',') .. ') ' ..
'return function(x) return ' .. fs .. ' end ' ..
'end)(...)'
)
return assert( loadstring(chunk_str) )( unpack(varvalues, 1, nvars) )
end
local a = 1;
local f = fcreate({a=a}, 'x+a')
print(f(1), f(2))
2012-07-10 20:09:08
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在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中获取用户配置主目录的跨平台方法
"loadstring does not compile with lexical scoping",所以不,它无法看到
loadstring调用外的局部变量。这取决于情况,为什么你要使用
loadstring?Lua支持闭包作为一等值,所以我无法从你的例子中看出你为什么需要loadstring。你的例子:
u = fcreate("math.sin(x)+c")可以使用无需
loadstring或者fcreate函数来重写:u = function(x) return math.sin(x)+c end当然这与以下代码等价:
function u(x) return math.sin(x) + c end如果你要有用户可配置的表达式,然后要将其编译为某些其他函数,我可以看到使用
loadstring的情况,但你传递了c局部变量,这表明这不是这种情况。你是要制作某种自定义lambda语法吗?