• lua 高级


    io操作:

      io.input(filename):指定一个输入流,可以是标准输入stdin,也可以是一个文件路径,返回一个文件句柄;

      io.output(filename):指定一个输出流,可以是标准输出stdout,也可以是一个文件路径,返回一个文件句柄;

      io.lines():迭代器,从指定的输入流中读取一行;

      io.read():从指定的输入流中读取数据,如果不带参数默认读取一行,

        参数是"*all"则一次读取整个文件数据;

        参数是"*line",读取一行;

        参数是"*number",读取一个数字;

        参数是number,读取不超过number个字节的数据;

      io.write(buffer):将数据写入到指定的输出流中;

      io.open(filename, mode):打开一个文件,如果成功返回一个文件对象,如果失败返回nil;

        local file = io.open("1.txt", "rw")

        file:read()

        file:write("123")

        file:close()

        file:seek(where, offset): where的取值: "cur"相对于当前位置进行偏移,"end"相对于结束位置进行偏移,"set"相对于文件开始位置进行偏移。返回值都是当前位置。

      io.close(file):关闭一个打开的文件;

      实例:

      1. 使用io.lines和table.concat,concat比直接使用..连接符号的效率要高很多,特别针对大字符串:  

    local input = io.input("1.txt")
    local output = io.output("2.txt")
    
    t = {}
    for line in io.lines() do
        t[#t + 1] = line
    end
    local buffer = table.concat(t, "
    ")
    io.write(buffer)
    
    io.close(input)
    io.close(output)

      2. 直接使用read,一次读取所有数据:

    local input = io.input("1.txt")
    local output = io.output("2.txt")
    
    local buffer = io.read("*all")
    io.write(buffer)
    
    io.close(input)
    io.close(output)

    数据文件:

      lua作为脚步语言的一大特点就是可以将数据存在脚本文件中,然后通过执行“脚本数据文件”,就可以实现导入数据的功能。而且lua的设计的主要用途之一就是针对数据进行描述,在这方面lua进行了大量的优化,因此使用lua脚本来描述数据,比通过文件io操作更加高效:

      实例:

      data.lua,数据描述脚本文件:

    load_data({"xiaoming",
        "20",
        "1000"
    })
    
    load_data({"xiaoqiang",
        "18",
        "2000"
    })

      data_load.lua,数据导入脚本文件,通过定义一个导入方法,就可以将数据导入到当前的运行环境中:

    t = {}
    function load_data(data)
    t[#t + 1] = data
    end
    
    local f = assert(loadfile("./data.lua"));
    f()
    
    for i, data in ipairs(t) do
        print(i, data[1])
    end

    序列化:

      将一个table中的数据,序列化成json数据:

    t = { 1, 2, 3, [5] = "df", ["s"] = "212", k = "212", f = {"a", "b", "c"}, j = {{"df", "fd", "d", x = 1, y = 2}, {1, 2,3}} }
    
    function serialize(tbl)
        local buffer_list = {}
        local arr_list = {}
        local value_list = {}
        local value_string = ""
    
        local quot = """
        local colon = ":"
        local comma = ","
        local lbrace = "{" rbrace = "}"
        local lsbracket = "[" rsbracket = "]"
    
        local hasArr = false
        local hasValue = false
    
        buffer_list[#buffer_list + 1] = "{"
        repeat
            for key, value in ipairs(tbl) do
                if (not hasArr) then
                    hasArr = true
                end
    
                local typestr = type(value)
                if typestr == "string" then
                    arr_list[#arr_list + 1] = quot..value..quot
                elseif typestr == "table" then
                    local subbuf = serialize(value)
                    arr_list[#arr_list + 1] = subbuf
                else
                    arr_list[#arr_list + 1] = value
                end
            end
        until true
        if (hasArr) then
            local keystr = ""arr""
            local arrstr = table.concat(arr_list, comma);
    
            value_list[#value_list + 1] = keystr..":["..arrstr.."]"
        end
        repeat
            for key, value in pairs(tbl) do
                repeat
                    local keytype = type(key)
                    if keytype == "number" then
                        break
                    end
    
                    if not hasValue then
                        hasValue = true
                    end
    
                    local keystr = """..key.."":"
                    local typestr = type(value)
                    if typestr == "string" then
                        value_list[#value_list + 1] = keystr.."""..value.."""
                    elseif typestr == "table" then
                        local subbuf = serialize(value)
                        value_list[#value_list + 1] = keystr..subbuf
                    else
                        value_list[#value_list + 1] = keystr..value
                    end
                until true
            end
        until true
        if (hasArr or hasValue) then
            value_string = table.concat(value_list, ",")
    
            buffer_list[#buffer_list + 1] = value_string
        end
        buffer_list[#buffer_list + 1] = "}"
    
        local buffer = table.concat(buffer_list)
        print(buffer)
    
        return buffer
    end
    
    serialize(t)

      打印结果:

    {
        "arr": [
            1,
            2,
            3
        ],
        "s": "212",
        "j": {
            "arr": [
                {
                    "arr": [
                        "df",
                        "fd",
                        "d"
                    ],
                    "y": 2,
                    "x": 1
                },
                {
                    "arr": [
                        1,
                        2,
                        3
                    ]
                }
            ]
        },
        "k": "212",
        "f": {
            "arr": [
                "a",
                "b",
                "c"
            ]
        }
    }

    元表:

      元表本身是一种table,它可以为其他table定义了一套预定义的操作集合,这类操作集合称为“元方法”。

      算术类的元方法:

        _add:加法;__mul:乘法;__sub:减法;__div:除法;_unm:相反数;__mod:取模;__pow:幂;__concat:连接符;

      关系符元方法:

        __eq:等于;__le:小于等于;__lt:小于;

        等于操作符必须是两个对象拥有相同的元方法时候才会被调用,否则会返回false;

      __index:当在一个对象中无法找到一个key字段时,会返回nil。但如果为其设置了元表,并定义__index元方法,就会返回调用__index的返回值。__index元方法通常是一个函数,但也可以是一个table,如果是一个table,就对该table应用相同的方式进行查找。先检查table中是否存在该字段,如果存在返回该字段的值,如果没有找到,检查table的元表中的__index元方法,以此类推;

      __newindex:当对对象中的某个字段进行赋值操作时,lua会去搜索元表中是否定义了__newindex元方法,如果存在就调用元方法,反之就会进行一次普通的赋值操作。如果_newindex元方法指向的是一个table,那么相同的操作会应用在table上;

      lua还提供了两个可以避开__index和__newindex元方法的函数:rawset(t, key, value)和rawget(t, key);

      实例:

    local mt = {}
    local Point = {}
    
    mt.default = { x = 0, y = 0, r = 255, g = 255, b = 255, a = 255 }
    mt.__add = function (t1, t2)
        return Point.new(t1.x + t2.x, t1.y + t2.y)
    end
    mt.__concat = function (t1, t2)
        local x = t1.x + t2.x
        local y = t1.y + t2.y
        return "x:"..x.." y:"..y
    end
    mt.__le = function (t1, t2)
        return t1.x <= t2.x and t1.y <= t2.y
    end
    mt.__eq = function (t1, t2)
        return t1.x == t2.x and t1.y == t2.y
    end
    mt.__tostring = function (t)
        return "Point x:"..t.x..",y:"..t.y
    end
    mt.__index = mt.default // 直接用table来索引,性能更好
    -- function (t, k)
    --     return mt.default[k]
    -- end
    mt.__newindex = --mt.default // 用table作为元方法,会把新的字段赋值给table
    function(t, k, v)
        rawset(t, k, v) // 跳过元方法,否则会堆栈溢出
    end
    mt.__metatable = "Point metatable"
    
    Point.new = function (x, y)
        assert(type(x) == "number" and type(y) == "number", "Point.new invaild arguments")
    
        local pt = {}
        setmetatable(pt, mt)
        pt.x = x
        pt.y = y
        return pt;
    end
    
    local p1 = Point.new(3, 41)
    local p2 = Point.new(4, 5)
    local p3 = p1 + p2 // 调用__add元方法
    local str = p1..p2 // 调用__concat元方法
    
    print(p3) // Point x:7,y:46
    print(p3.x, p3.y) // 7 46
    print(str) // x:7 y:46
    print(p1 == p2) // false 调用__eq元方法
    print(p3.r) // 255 调用__index元方法,从mt.default表中去查找
    print(rawget(p3, "r")) // nil 由于避开了__index元方法,所以返回nil
    p3.c = 123 // 调用__newindex元方法进行赋值
    print(p3.c) // 123
    print(p1.c) // nil 因为c字段是赋值给p3的,p1无法访问
    print(rawget(p3, "c")) // 123 说明c是直接复制给p3的,没有放在元表上
    print(mt.default["c"]) // nil 说明c是直接复制给p3的,没有放在元表上

      table的代理:

      使用代理的table,可以跟踪对原始table的访问,并可以限制对原始table的控制。

      

    local _t = {x = 2, y = 3, z = 4}
    
    local mt = {
        __index = function (t, k)
            print("proxy __index", t, k)
            return t._t[k];
        end,
    
        __newindex = function (t, k, v)
            print("proxy __newindex", t, k, v)
            t._t[k] = v
        end
    }
    
    function create_proxy (tbl)
        local proxy = {}
        proxy._t = tbl;
        setmetatable(proxy, mt)
        return proxy;
    end
    
    proxy_t = create_proxy(_t);
    
    proxy_t.z = 123
    proxy_t.z1 = 456
    print(proxy_t.x, proxy_t.y, proxy_t.z, proxy_t.z1)

      打印结果:

    proxy __newindex    table: 0x7fb1d2408e10    z    123
    proxy __newindex    table: 0x7fb1d2408e10    z1    456
    proxy __index    table: 0x7fb1d2408e10    x
    proxy __index    table: 0x7fb1d2408e10    y
    proxy __index    table: 0x7fb1d2408e10    z
    proxy __index    table: 0x7fb1d2408e10    z1
    2    3    123    456

    模块:

      使用require来导入一个模块,可以是lua模块,也可以是c模块。

      require的搜索策略:替换环境变量配置中的?(unix通常是:./?.lua;/usr/local/lua/?.lua;/usr/local/lua/?/init.lua),如果模块名中含有.,将.替换成目录分隔符(unix是/,windows是)。例如 require "a.b" 会搜索如下路径:

    lua: /Users/avl-showell/Desktop/lua-5.3.3/test/test1.lua:3: module 'a.b' not found:
        no field package.preload['a.b']
        no file '/usr/local/share/lua/5.2/a/b.lua'
        no file '/usr/local/share/lua/5.2/a/b/init.lua'
        no file '/usr/local/lib/lua/5.2/a/b.lua'
        no file '/usr/local/lib/lua/5.2/a/b/init.lua'
        no file './a/b.lua'
        no file '/usr/local/lib/lua/5.2/a/b.so'
        no file '/usr/local/lib/lua/5.2/loadall.so'
        no file './a/b.so'
        no file '/usr/local/lib/lua/5.2/a.so'
        no file '/usr/local/lib/lua/5.2/loadall.so'
        no file './a.so'
    function require (name)
        if not package.loaded[name] then
            local loader = findloader(name)
            if loader == nil then
                error("unable to load module "..name)
            end
            package.loaded[name] = true
            local res = loader(name)
            if res ~= nil then
                package.loaded[name] = res
            end
        end
        return package.loaded[name]
    end

      模块创建方式:

    local M = {}
        ......
    _G[modulename] = M;
    package.loaded[modulename] = M
    return M
  • 相关阅读:
    group by与聚合函数
    表联结
    项目延期 怎样规避风险
    虚拟机安装linux系统
    Cannot truncate a table referenced in a foreign key constraint
    李航--《统计学习方法总结》
    CART算法
    北航学长分享交流笔记
    CentOS7导入MySql数据表结构并显示表结构
    RedHat7安装mysql5.7数据库
  • 原文地址:https://www.cnblogs.com/iRidescent-ZONE/p/5644399.html
Copyright © 2020-2023  润新知