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 + ] = 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",
"",
""
}) load_data({"xiaoqiang",
"",
""
})
data_load.lua,数据导入脚本文件,通过定义一个导入方法,就可以将数据导入到当前的运行环境中:
t = {}
function load_data(data)
t[#t + ] = data
end local f = assert(loadfile("./data.lua"));
f() for i, data in ipairs(t) do
print(i, data[])
end
序列化:
将一个table中的数据,序列化成json数据:
t = { , , , [] = "df", ["s"] = "", k = "", f = {"a", "b", "c"}, j = {{"df", "fd", "d", x = , y = }, {, ,}} } 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 + ] = "{"
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 + ] = quot..value..quot
elseif typestr == "table" then
local subbuf = serialize(value)
arr_list[#arr_list + ] = subbuf
else
arr_list[#arr_list + ] = value
end
end
until true
if (hasArr) then
local keystr = "\"arr\""
local arrstr = table.concat(arr_list, comma); value_list[#value_list + ] = 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 + ] = keystr.."\""..value.."\""
elseif typestr == "table" then
local subbuf = serialize(value)
value_list[#value_list + ] = keystr..subbuf
else
value_list[#value_list + ] = keystr..value
end
until true
end
until true
if (hasArr or hasValue) then
value_string = table.concat(value_list, ",") buffer_list[#buffer_list + ] = value_string
end
buffer_list[#buffer_list + ] = "}" 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 = , y = , r = , g = , b = , a = }
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(, )
local p2 = Point.new(, )
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 = , y = , z = } 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 =
proxy_t.z1 =
print(proxy_t.x, proxy_t.y, proxy_t.z, proxy_t.z1)
打印结果:
proxy __newindex table: 0x7fb1d2408e10 z
proxy __newindex table: 0x7fb1d2408e10 z1
proxy __index table: 0x7fb1d2408e10 x
proxy __index table: 0x7fb1d2408e10 y
proxy __index table: 0x7fb1d2408e10 z
proxy __index table: 0x7fb1d2408e10 z1
模块:
使用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./test/test1.lua:: 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
lua 高级的更多相关文章
- Lua高级教程Metatables
什么是Metatable metatable是Lua中的重要概念,每一个table都可以加上metatable,以改变相应的table的行为. Metatables举例 -- 声明一个正常的关系变量 ...
- [Lua]Lua高级教程Metatables
什么是Metatable metatable是Lua中的重要概念,每一个table都可以加上metatable,以改变相应的table的行为. Metatables举例 -- 声明一个正常的关系变量 ...
- (原创)cocos lua 热更新从零开始(一)最简单demo
开发环境:WIN7 + cocos2dx 3.10 lua版本 0.学习这篇内容的基础是你要会创建并运行一个cocos lua项目 1.热更新的思想所谓的热更新,就是在线更新代码和资源.热更新的过程首 ...
- java高级精讲之高并发抢红包~揭开Redis分布式集群与Lua神秘面纱
java高级精讲之高并发抢红包~揭开Redis分布式集群与Lua神秘面纱 redis数据库 Redis企业集群高级应用精品教程[图灵学院] Redis权威指南 利用redis + lua解决抢红包高并 ...
- class() 高级用法 -- lua
class() 高级用法 class() 除了定义纯 Lua 类之外,还可以从 C++ 对象继承类. 比如需要创建一个工具栏,并在添加按钮时自动排列已有的按钮,那么我们可以使用如下的代码: -- 从 ...
- Lua学习高级篇
Lua学习高级篇 之前已经说了很多,我目前的观点还是那样,在嵌入式脚本中,Lua是最优秀.最高效的,如果您有不同的观点,欢迎指正并讨论,切勿吐槽.这个系列完全来自于<Programming in ...
- lua中文教程【高级知识】
一.编译和运行和调试 1.lua和其他解释型语言一样,先转换成为中间码再执行 2.dofile和loadfile的区别:loadfile编译返回不执行,返回错误代码:dofile执行,返回错误信息 3 ...
- lua 脚本之高级篇 (面向对象的完全支持),有性能问题。
---------------------------------------------------------- --面向对象核心库 ------------------------------- ...
- c++调用lua
我们主要解决如下几个问题: 转:http://www.cnblogs.com/zisou/p/cocos2dx-lua2.html http://www.cnblogs.com/sevenyuan/p ...
随机推荐
- python3 使用pyperclip读写剪贴板(windows)
2016年5月14日 03:41:38 codegay 使用pyperclip库读写剪贴板非常简单~, 1.使用命令安装: pip install pyperclip 2.然后...就可以了: 以下是 ...
- cookie窃取和session劫持
Updates 2014-08-17 感谢@搞前端的crosser的提醒,加入了HTTP Response Splitting的内容. 此篇文章的Presentation戳这里. 一.cookie的基 ...
- 在文章没有缩略图的时候,如何去掉织梦官方的 DEDECMS无缩略图 图片
1.打开 list_article.htm.2.替换代码 将 [field:array runphp='yes']@me = (empty(@me['litpic']) ? “<a href=’ ...
- As 和 Is的区别
首先来说说As是干什么的: 代码: void OnMouseEnter(object sender, MouseEventArgs e){ Ellipse ell = sender as Ellips ...
- [转]使用 C 编写 Lua 模块
Lua 作为一种小巧的语言,一般都是嵌入到 C/C++ 中作为扩展语言,但是也可以作为独立的脚本语言使用,并且可以使用 C/C++ 编写扩展模块.在参考资料 [1] 中有怎样用 C/C++ 编写模块的 ...
- 启动运行下载gradle速度太慢,手动添加
启动运行下载gradle速度太慢,并且容易卡死(感谢群友ˋ狠ㄨ得意提供支持)---国内网络访问地址 我们经常运行项目的时候会需要进行下载gradle,不过由于网络或者和谐的问题经常下载需要花很长时间或 ...
- Generator 函数学习笔记
// 使用 function* 定义一个 generator 函数 function* helloWorldGenerator() { yield 'hello'; // yield 关键字作为暂停的 ...
- 程序跳转到访问一个确定的地址0x100000
用函数指针 把这个确定的地址转化成一个函数指针 这就明白了程序中调用函数的意义 测试代码如下: #include <stdio.h> void getMemory() { printf(& ...
- windows下面安装Python和pip
windows下面安装Python和pip 安装Python 第一步,我们先来安装Python, https://www.python.org/downloads/ 这里选择的是2.7.10 第二步. ...
- 【C】 01 - 再学C语言
“C语言还用再学吗?嵌入式工程师可是每天都在用它,大家早就烂熟于心,脱离语言这个层面了”.这样说不无道理,这门古老的语言以其简单的语法.自由的形式的而著称.使用C完成工作并不会造成太大困扰,所以很少有 ...