• lua 序列化[de]serialize 支持 循环(cycle reference)、嵌套(nest) 引用


    早已实现,想到个好的方式。兼顾可读性折叠

    流程:

    1. 分析出单例、多引用,编号,仅考虑后者。
    2. 代码执行顺序固定,如:
    local o=''
    local function p(i)
        o=o..i
    end
    assert({
        p'1',
        a={
            p'2',
            b={p'3'},
            p'4'
        },
    } and o=='1234')
    View Code
    1. 在首次使用处插入定义,如 R(i,{..}) ,在后续引用处仅仅使用 R[i] 即可。
    2. 对测试例 t={} t[t]=t t.T=t 生成的代码如:
    local R=setmetatable({},{
        __index=function(R,id) R[id]={} return R[id] end,
        __call=function(R,id,t)
            if rawget(R,id) then
                for k,v in pairs(t) do--copy
                    R[id][k]=v
                end
                t=R[id]
            end
            R[id]=t
            return t
        end,
    })
    return R(1,{[R[1]]=R[1],["T"]=R[1],})
    View Code

    脚本(100行,含缩进、键、数组优化、测试,未支持函数)

    --by RobertL https://www.cnblogs.com/RobertL/p/14258259.html
    local T,P,I,F,SF,C,RP=type,pairs,table.insert,math.floor,string.format,table.concat,string.rep
    function D(d)--data to string
        local ts={--[[tables
            [t]=true/false,--has reference
            [id]=true/flase,--could refer (or define at first time)
        ]]}
        local t
        local function S(i)--scan(input)
            t=T(i)
            if t=='table' or (t=='string' and i:len()>10) then
                if not ts[i] then
                    ts[i]=ts[i]==false
                else return end
                if t=='table' then for k,v in P(i) do
                    S(k);S(v)
                end end
            end
        end
        S(d)
        
        --generate id, clean single instance
        local id=1
        for t,r in pairs(ts) do
            if r then
                ts[t],id=id,id+1
            else
                ts[t]=nil
            end
        end
    
        local o={--output list
        [[--Generated using Data2String2.lua by RobertL
    local _=setmetatable({},{
        __index=function(R,id) R[id]={} return R[id] end,
        __call=function(R,id,t)
            if rawget(R,id) then
                for k,v in pairs(t) do--copy
                    R[id][k]=v
                end
                t=R[id]
            end
            R[id]=t
            return t
        end,
    })
    return ]]}
        local function W(t)--write
            if T(t)=='boolean' then
                print'her'
            end
            t=t=='' and '
    ' or t
            I(o,t)
        end
        local function I(n)--indent(number)
            W(RP('	',n))
        end
        local function R(i,n,c)--reference(input,config,indent number,cofiger)
            t=T(i)
            local id=t~='number' and ts[i]
            if id then
                W'_'
                if ts[id] then
                    W'['W(id)W']'
                    return
                else
                    W'('W(id)W','
                    ts[id]=id
                end
            end
            if t=='string' then
                W(SF('%q',i))
            elseif t=='number' then
                if i==F(i) then
                    i=F(i)--convert to integer
                end
                W(i)
            elseif t=='boolean' then
                W(i and 'true' or 'false')
            elseif t=='nil' then
                W'nil'
            elseif t=='table' then
                W'{'
                local is={}
                for ix,v in ipairs(i) do
                    W''I(n+1)
                    R(v,n+1)W','
                    is[ix]=true
                end
                for k,v in P(i) do
                    if not is[k] then
                        W''I(n+1)
                        if not (T(k)=='string' and SF(k,'^[%a_]%w*$') and (W(k) or true)) then
                            W'['R(k,n+1)W']'
                        end
                        W'='R(v,n+1)W','
                    end
                end
                W''I(n)W'}'
            end
            if id then
                W')'
            end
        end
        R(d,0)
        
        return C(o)
    end
    if not ... then
        local t={}
        t[t]=t
        t.T=t
        local t2=load(D(t))()
        assert(t2[t2]==t2 and t2.T==t2)
        --
        t={}
        t.T={T1=t}
        t2=load(D(t))()
        assert(t2.T.T1==t2)
        --
        t={a=1.0,b='string','long long string','long long string',[{[false]=false,false,}]=false}
        print(D(t))
    end
    return D
    View Code

    待,支持外部引用,内部依赖检测。

    格式测试:

    t={['a key']=1.0,'short string','long long string','long long string',[{[false]=false,false,}]=false}

    return {
        "short string",
        _(1,"long long string"--[[2]]),
        _[1],
        [{
            false,
            [false]=false,
        }]=false,
        ["a key"]=1,
    }
    View Code
  • 相关阅读:
    智能安全实验室-全能优化(Guardio) 3.8.0.460:紧急修复功能列表点击“导出(/列表)”出现错误的问题
    Guardio全能优化3.2.0.400
    智能安全实验室-全能优化(Guardio) 3.8.0.482:修正部分错误
    智能安全实验室-Defendio杀马2.4.0.420-实时防护-内存防护、新浏览器导航界面
    智能安全实验室-杀马(Defendio) 2.3.0.409 :任务计划,用户可以定时对指定目标进行扫描、智能更新等
    微软同步框架入门之五使用WCF同步远程数据
    微软同步框架入门之四冲突(Conflict)检测和处理
    小A是支枪,子弹未打光之"步枪"篇
    微软同步框架入门之三分析生成的同步类文件
    微软同步框架入门之二增量和修改同步方式
  • 原文地址:https://www.cnblogs.com/RobertL/p/14258259.html
Copyright © 2020-2023  润新知