Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Lua和序列化闭包_Lua_Closures - Fatal编程技术网

Lua和序列化闭包

Lua和序列化闭包,lua,closures,Lua,Closures,我正在尝试序列化和反序列化Lua闭包 我的基本理解是,下面的工厂应该生成闭包(Lua对函数和闭包没有太大的区别——也就是说,没有“闭包”类型) 文件很清楚。string.dump不使用upvalue处理闭包。这是因为upvalue可以是任何东西(包括userdata,Lua如何知道如何序列化它?) upvalues是由于作用域/闭包而对函数而言是局部的外部变量。由于示例中的x是ffactory返回的函数的upvalue,因此它不会被序列化 如果您希望以某种方式支持此功能,则必须自己存储UpVal

我正在尝试序列化和反序列化Lua闭包

我的基本理解是,下面的工厂应该生成闭包(Lua对函数和闭包没有太大的区别——也就是说,没有“闭包”类型)


文件很清楚。string.dump不使用upvalue处理闭包。这是因为upvalue可以是任何东西(包括userdata,Lua如何知道如何序列化它?)

upvalues是由于作用域/闭包而对函数而言是局部的外部变量。由于示例中的x是ffactory返回的函数的upvalue,因此它不会被序列化

如果您希望以某种方式支持此功能,则必须自己存储UpValue,并在反序列化函数后再次设置它们,如下所示:

function ffactory(x)
    return function() return x+1 end
end

local f1 = ffactory(5)
print(f1())

local s = string.dump(f1)
f2 = loadstring(s)
debug.setupvalue(f2, 1, 5)
print(f2())

您可以执行类似的操作来保存/恢复这些upvalues(注意,它不会处理不同函数之间共享的upvalues):

现在,如果还原upvalues,则会得到相同的结果,但如果不还原upvalues,则会在Lua 5.2下出现运行时错误:

lua.exe: upvalues.lua:19: attempt to index upvalue '_ENV' (a nil value)
stack traceback:
upvalues.lua:19: in function 'f2'
upvalues.lua:24: in main chunk
[C]: in ?

非常感谢。我不知道debug.setupvalue。您能告诉我在文档中的什么地方解释了string.dump对upvalue的处理(不在这里:)。另外,在我的第一个示例中,_ENV的返回是预期的行为吗?您可以阅读关于debug.getupvalue的内容。我不确定您的第一个示例中的交易是什么,因为它甚至不应该编译。您正在使用load(),但实际上应该使用loadstring()。加载需要一个func和一个字符串。不再需要了。Lua 5.2已经弃用了
loadstring
,并且只对字符串和函数使用
load
loadstring
仍然可用,但是,它给出的结果与
load
相同。再次感谢!啊,明白了。我几乎仍然只使用5.1,所以我没有意识到这一变化!Mike,如果设置了
Lua\u COMPAT\u loadstring
Lua\u COMPAT\u ALL
,则可以在Lua 5.2中使用
loadstring
function ffactory(x)
    return function() return x+1 end
end

local f1 = ffactory(5)
print(f1())

local s = string.dump(f1)
f2 = loadstring(s)
debug.setupvalue(f2, 1, 5)
print(f2())
local function capture(func)
  local vars = {}
  local i = 1
  while true do
    local name, value = debug.getupvalue(func, i)
    if not name then break end
    vars[i] = value
    i = i + 1
  end
  return vars
end

local function restore(func, vars)
  for i, value in ipairs(vars) do
    debug.setupvalue(func, i, value)
  end
end  

function ffactory(x) return function() return x end end
local f1 = ffactory(5)
local f2 = (loadstring or load)(string.dump(f1))
restore(f2, capture(f1)) --<-- this restored upvalues from f1 for f2

print(f1(), f2())
function ffactory(x) return function() math.abs(0) return x end end
lua.exe: upvalues.lua:19: attempt to index upvalue '_ENV' (a nil value)
stack traceback:
upvalues.lua:19: in function 'f2'
upvalues.lua:24: in main chunk
[C]: in ?