serialization - 如何在 Lua 中序列化元表?
问题描述
local binser = require "binser"
local log, floor, ceil, min, random = math.log, math.floor, math.ceil, math.min, math.random
local makeNode = function(value,size)
return {
value=value,
next={},
width={},
size=size
}
end
local End ={}
local NIL = makeNode(End,0)
local insert = function(self,value)
local node, chain, stepsAtLevel = self.head, {}, {}
for i=1, self.maxLevel do stepsAtLevel[i]=0 end
for level = self.maxLevel, 1, -1 do
while node.next[level] ~= NIL and node.next[level].value <= value do
stepsAtLevel[level] = ( stepsAtLevel[level] or 0 ) + node.width[level]
node = node.next[level]
--print(level, stepsAtLevel[level],value)
end
chain[level]=node
end
local nodeLevel = min( self.maxLevel, - floor(log(random()) / log(2) ) )
local newNode = makeNode( value, nodeLevel)
local steps, prevNode = 0
for level= 1, nodeLevel do
prevNode = chain[level]
newNode.next[level] = prevNode.next[level]
prevNode.next[level] = newNode
newNode.width[level] = prevNode.width[level] - steps
prevNode.width[level] = steps + 1
steps = steps + stepsAtLevel[level]
end
for level = nodeLevel + 1, self.maxLevel do
chain[level].width[level] = chain[level].width[level] +1
end
self.size = self.size + 1
end
local first = function(self)
return self.head.next[1].value
end
local tostring = function (self)
local t = {}
for k,v in self:ipairs() do table.insert(t,v) end
return "( "..table.concat(t,", ").. " )"
end
local islMT = {
__index = function(self,i)
if type(i) ~= "number" then return end
if i > self.size then return end
local node = self.head
for level=self.maxLevel, 1, -1 do
while node.width[level] <= i do
i = i - node.width[level]
node = node.next[level]
end
end
return node.value
end,
__tostring=tostring
}
local ipairs = function (self)
local node, size = self.head.next[1] , self.size
count = 0
return function()
value=node.value
node = node.next[1]
count = count+1
return count <= size and count or nil, value
end
end
math.randomseed(os.time())
local size = expected_size or 16
if not expected_size then
expected_size = 16
end
local maxLevel = floor( log(expected_size) / log(2) )
local head = makeNode("HEAD",maxLevel)
for i=1,maxLevel do
head.next[i] = NIL
head.width[i] = 1
end
local insdel = setmetatable( {
size = 0,
head = head,
maxLevel = maxLevel,
insert = insert,
tostring = tostring,
ipairs=ipairs,
}, islMT
)
insdel:insert('foo')
print(insdel)
-- how to serialize metatable insdel? this fail
local ser = binser.serialize(insdel)
insdel = binser.deserialize(ser)
insdel:insert('bar')
print(insdel)
我尝试了无数的序列化模块(蛇、json、冥王星),但没有一个适用于元表,有人知道如何序列化元表吗?使用哪个模块来序列化/反序列化元表以及如何?
包含完整代码,binser 模块来自 luarocks: https ://luarocks.org/modules/bakpakin/binser
解决方案
推荐阅读
- ios - iCloud 中等效的应用程序数据文件夹
- c# - 如何检测与实例化预制件的冲突
- python - 你如何从 discord.py 中获得用户头像?
- entity-framework - .Error CS1061 '任务
' 不包含 'Where' 的定义,也没有可访问的扩展方法 'Where' - azure-data-factory - ADF 复制活动接收器预复制脚本超时
- r - 如何在R中以数字方式修复拟合概率0或1发生警告
- python - 我无法让 pandas 正确合并我的数据框
- typescript - 打字稿编译什么都不做
- typescript - 使用打字稿在 Expo 40+ 中加载降价文件
- php - 为什么 php 将某些字符转换为“?”