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, "\n")
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

 

转载于:https://www.cnblogs.com/iRidescent-ZONE/p/5644399.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值