lua

2018-08-28 15:06:47 浏览数 (1)

游戏里面用lua来热更新的 redis的默认方法也是lua(我觉得是因为和nosql很搭)

变量

  1. 全局变量直接使用的时候为nil
  2. 数组下标从0开始(不推荐)a = {[0]="123","32","23"};
  3. 支持多返回值,多个同时赋值,只需要一个时候使用哑元_
  4. 尽量避免一个下划线开头 大写字母
  5. ---[[可以注销掉块注释
  6. type函数永远返回一个字符串
  7. lua将falsenil视为假,将0和空字符串视为真
  8. LUA对于小于1014的数字用双精度没有四舍五入的浮点误差,合法的数字写法:4,0.4,4.58e-3,0.3e12,5e 20
  9. Lua的字符串是只读的,<ddd>表达数值转义,[[ ]],[===[ ]===]界定换行字符串,(类似的界定注释)
  10. tonumber, tostring不成功返回nil
  11. #a获取字符串a的长度,table.maxn对于nil更加安全
  12. table永远是匿名的,a ={},b=ab保持了一个对于a所指向table的引用
  13. a.xa["x"]是一样的,点作为记录,key暗示任意字符串
  14. x - x%1取整
  15. x,y=y,x交换
  16. do end构成基本块(local)

I/O

代码语言:javascript复制
a = io.read("*number")print(a)

function

notes

  1. 如果要在函数中间使用return,需要加do return end
  2. 可变参数(...), 获取arg
  3. 尾调用不保留调用者栈,这种情况下不会栈溢出, goto(用来编写状态机)
  4. 若将函数返回值作为不是最后一个的表达式,保留第一个返回值
  5. 如果函数调用在单独的一个圆括号里面,只能返回一个结果
  6. 函数名只是持有某个函数的变量
  7. 函数内部变量是一个closure,相当于对象的private variable

example

sort

代码语言:javascript复制
table.sort(tb, function(a,b) return (a.name > b.name) end

3-var

代码语言:javascript复制
-- 对于and来说第一个操作数为真,返回第二个操作数-- or第一个操作数为假,返回第二个操作数(a and b) or c  -- a ? b : c, b不可以为false

unnamed

代码语言:javascript复制
foo = function(x) return 2 * x end

递归

需要先定义局部变量

代码语言:javascript复制
local fact -- 这一句和下一句要求分开【bug主要在这里】fact = function(n)if n == 0 then return 1else return n * fact(n-1)endendorlocal function fact(n)    if n==0 then return 1    else return n * fact(n-1)    endend

闭包

内部的函数体可以访问外部函数的局部变量(upvalue)

domo 重定义限制程序打开文件

代码语言:javascript复制
do    local oldOpen = io.open    io.open = function(filename, mode)        if access_OK(filename, mode) then            return oldOpen(filename, mode)        else            return nil, "access denied"        end    endend

局部函数

代码语言:javascript复制
-- g can use f herelocal f = function(...)endlocal g = function(...)f()end

递归局部函数

需要先声明

代码语言:javascript复制
local factfact = function(n)    if n == 0 then        return 1    else        return n * fact(n-1)    endend

tables

代码语言:javascript复制
a = {}; a.x = 1;b = {}; b.x = 1;a ~= ba.foo = function(x,y) return x   y endunpack(a)-- 分离一层

block

normal

代码语言:javascript复制
do    local i = 1enddo return end -- 用于调试

if, while, repeat

代码语言:javascript复制
if conditions thenelseif conditions thenendwhile condition doendrepeat    statements;until conditions;

for

代码语言:javascript复制
for var = beg,end,step do -- 如果为表达式一次性求职endfor i,v in ipairs(a)doendfor key in pairs(v)doend-- 死循环for i = 1,math.huge doend

iterator

  1. 使用闭包实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15function list_iter(t) local i = 0 local n = table.getn(t) return function() i = i 1 if i <= n then return t[i] end end end t = {1,2,3} iter = list_iter(t) while true do local element = iter() if element == nil then break end print(element)
  2. 范性for本身实现for <var-list> in <exp-list> do end
  3. 无状态的迭代器for i,v in ipairs(a) do end

编译运行

  1. require 会搜索目录加载文件,避免同一个文件
  2. load c 1 2local path = "/xxxx/xxx.so" loacl f= loadlib(path, "luaopen_socket")

错误

抛出

代码语言:javascript复制
if n then error("123") endassert(io.read("*number"), "123")

处理

代码语言:javascript复制
if n then error("123") endassert(io.read("*number"), "123")

协同程序

Lua将所有关于协同程序的函数放置在一个名为coroutine的table里面

代码语言:javascript复制
fco = coroutine.create(f) -- 创建,处于挂起状态coroutine.resume(fco) -- 启动或者再次启动coroutine.status(co) -- suspended/running/dead/normalcoroutine.yield() -- 函数内部挂起,yield(1,2)将返回1,2

非抢占式多线程 管道,迭代器

代码语言:javascript复制
fco = coroutine.create(f) -- 创建,处于挂起状态coroutine.resume(fco) -- 启动或者再次启动coroutine.status(co) -- suspended/running/dead/normalcoroutine.yield() -- 函数内部挂起,yield(1,2)将返回1,2

  1. 第一,加载 LuaSocket 库 require “luasocket”
  2. 第二,定义远程主机和需要下载的文件名 host = “www.w3.org" file = “/TR/REC-html32.html”
  3. 第三,打开一个 TCP 连接到远程主机的 80 端口(http 服务的标准端口) c = assert(socket.connect(host, 80)) 上面这句返回一个连接对象,我们可以使用这个连接对象请求发送文件 c:send(“GET “ .. file .. “ HTTP/1.0rnrn”) receive 函数返回他送接收到的数据加上一个表示操作状态的字符串。当主机断开连接时,我们退出循环。
  4. 第四,关闭连接 c:close()

自定义table参数

代码语言:javascript复制
-- t.__tostring = xxx-- set:local mt = { __index = t}setmetatable(proxy, mt) __tostring -- 打印__index -- t[x] getter__newindex -- t[x] setter

全局变量

代码语言:javascript复制
_G[x]

局部作用域

代码语言:javascript复制
-- 创建a = 1  -- create a global variable -- change current environment setfenv(1, {_G = _G}) _G.print(a)    --> nil _G.print(_G.a)  --> 1-- 继承a = 1 local newgt = {}    -- create new environment setmetatable(newgt, {__index = _G}) setfenv(1, newgt)   -- set it print(a)        --> 1

面向对象

代码语言:javascript复制
function Account:withdraw(v) -- a:withdrawfunction withdraw(self, v) -- a.withdraw(可以互相通用)
  1. 原表中实现类的方法,算术方法包括:__add,__mul,__sub,__div,__unm,__mod,__pow,关系方法包括__eq,__lt,__le
  2. 表中找不到会访问__index(t,k)方法,更新为__newindex(t,k,v)方法 1 2 3 4 5 6 7 8 9 10 11function setDefault(t,d) local mt = {__index=function() return d end} setmetatable(t,mt) end local key = {} -- trick, 唯一索引 local mt = {__index = function(t) return t[key] end} fuction setDefault(t,d) t[key] = d setmetatable(t,mt) end
  3. 新建对象 1 2 3 4 5function c:new(o) o = o or {} setmetatable(o,c) return o end

继承

代码语言:javascript复制
function Account:withdraw(v) -- a:withdrawfunction withdraw(self, v) -- a.withdraw(可以互相通用)

weak表

  • 如果将一些对象放到一个数组当中,Lua将不会回收他们
  • 如果一个对象只有弱引用指向它,那么gc会自动回收该对象的内存。
  • weak 表 一个weak引用 阻止 对象被回收,表的weak性由他的metatable__mode域来制定的,kkeyweak,vvalueweak1 2 3 4 5a, b = {}, {} setmetatable(a,b) b.__mode = "k" collectgarbage()

用途: 记忆函数,对象的属性关联

函数工厂

解析

setfenv(f, table):设置一个函数的环境   (1)当第一个参数为一个函数时,表示设置该函数的环境   (2)当第一个参数为一个数字时,为1代表当前函数,2代表调用自己的函数,3代表调用自己的函数的函数,以此类推

标准库

数学

简介

数学库由算术函数的标准集合组成,比如三角函数库(sin, cos, tan, asin, acos, etc.), 幂指函数(exp, log, log10),舍入函数(floor, ceil)、max、min,加上一个变量 pi。数学 库也定义了一个幂操作符(^)。 所有的三角函数都在弧度单位下工作。(Lua4.0 以前在度数下工作。)你可以使用 deg 和 rad 函数在度和弧度之间转换。

random

math.random 用来产生伪随机数,有三种调用方式:

  • 第一:不带参数,将产生 [0,1)范围内的随机数.
  • 第二:带一个参数 n,将产生 1 <= x <= n 范围内的随机数 x.
  • 第三:带两个参数 a 和 b,将产生 a <= x <= b 范围内的随机数 x. math.randomseed(os.time())

table

lua 假定array在最后一个非nil位置结束

代码语言:javascript复制
table.getn -- memory searchtable.setntable.insert(a,x) -- pushtable.remove(a) -- poptable.insert(a,1,x), table.remove(a,1)table.sort

string

代码语言:javascript复制
string.len(s)string.rep(s,n) -- repeat s for n timesstring.lower(s) -- upperstring.sub(s,i,j) -- begin with 1. end as -1i, j = string.find(s, "hello", [beg pos])s, count = string.gsub(ori, mod, replace[, time])

IO

简单模式/完全模式

代码语言:javascript复制
io.input(filename), io.output(filename)io.read() -- a lineio.read(*all)io.read(*number)io.read(*line)io.read(*num) --  char numio.read(0) -- whether EOFio.write("",math.sin(3),"")f = assert(io.open("xxx.xxx", "r"))local lines, rest = f:read(BUFISIZE,"*line")outf:flush

os

代码语言:javascript复制
io.input(filename), io.output(filename)io.read() -- a lineio.read(*all)io.read(*number)io.read(*line)io.read(*num) --  char numio.read(0) -- whether EOFio.write("",math.sin(3),"")f = assert(io.open("xxx.xxx", "r"))local lines, rest = f:read(BUFISIZE,"*line")outf:flush

debug

  1. 栈级别
  2. HOOK(call, return, line, count)

useful functions

代码语言:javascript复制
string.format(fmt.."%q", unpack(arg), "1234")table.sort(tb1, function(a,b) return (a.name>b.name) end)io.read(*all)

(私货)SimpleFramework

既然你看到了最后,不如看下传统热更新框架~~ 1 2 3 4 5 6xxxPanel.prefab, xxx.AssetBundle=>build Windows Resource GlobalGenerator:OnResourceInited->LuaScriptPanel->xxxPanel GameManager.Lua->OnInitOK()->CtrlManager.Init() Define.Lua:"xxx=xxxCtrl" GameManager.Lua:ctrl:Awake() LayerPanel

0 人点赞