啊哈!达

突然想到你,笑了笑自己。

Programming in Lua 笔记

变量

  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

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

function foo(x) return 2 * x end
==
foo = function (x) return 2 * x end


--
function derivative(f, delta)
    delta = delta or 1e-4
    return function(x)
        return (f(x+delta) - f(x))/delta
    end
end

sort

table.sort(tb, function(a,b) return (a.name > b.name) end

3-var

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

unnamed

foo = function(x) return 2 * x end

递归

需要先定义局部变量

local fact -- 这一句和下一句要求分开【bug主要在这里】
fact = function(n)
if n == 0 then return 1
else return n * fact(n-1)
end
end

or

local function fact(n)
    if n==0 then return 1
    else return n * fact(n-1)
    end
end

闭包

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

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

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
    end
end

局部函数

-- g can use f here
local f = function(...)
end
local g = function(...)
f()
end

递归局部函数

需要先声明

local fact
fact = function(n)
    if n == 0 then
        return 1
    else
        return n * fact(n-1)
    end
end

tables

a = {}; a.x = 1;
b = {}; b.x = 1;
a ~= b

a.foo = function(x,y) return x + y end
unpack(a)-- 分离一层

block

normal

do
    local i = 1
end
do return end -- 用于调试

if, while, repeat

if conditions then
elseif conditions then
end

while condition do
end

repeat
    statements;
until conditions;

for

for var = beg,end,step do -- 如果为表达式一次性求职
end

for i,v in ipairs(a)
do
end

for key in pairs(v)
do
end

-- 死循环
for i = 1,math.huge do
end

iterator

  1. 使用闭包实现
function 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)
  1. 范性for本身实现for <var-list> in <exp-list> do end
  2. 无状态的迭代器for i,v in ipairs(a) do end

编译运行

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

错误

抛出

if n then error("123") end
assert(io.read("*number"), "123")

处理

function foo()
    error()
end

if pcall(foo) then
    -- no error
else
    -- error
    print(debug.traceback())
    -- or next way
    local status, err = pcall(xxx):
    print(err)
end

协同程序

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

fco = coroutine.create(f) -- 创建,处于挂起状态
coroutine.resume(fco) -- 启动或者再次启动
coroutine.status(co) -- suspended/running/dead/normal

coroutine.yield() -- 函数内部挂起,yield(1,2)将返回1,2

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

co = coroutine.create(func)
-- print(co)
-- print(coroutine.status(co)) 
-- suspended(创建成功,yeild), running, dead
-- coroutine.resume(co)
-- coroutine.yield()
  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.0\r\n\r\n”)
    receive 函数返回他送接收到的数据加上一个表示操作状态的字符串。当主机断开连接时,我们退出循环。
  4. 第四,关闭连接
    c:close()

自定义table参数

-- t.__tostring = xxx
-- set:
local mt = { __index = t}
setmetatable(proxy, mt) 

__tostring -- 打印
__index -- t[x] getter
__newindex -- t[x] setter

全局变量

_G[x]

局部作用域

-- 创建
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 

面向对象

function Account:withdraw(v) -- a:withdraw
function withdraw(self, v) -- a.withdraw(可以互相通用)
  1. 原表中实现类的方法,算术方法包括:__add,__mul,__sub,__div,__unm,__mod,__pow,关系方法包括__eq,__lt,__le
  2. 表中找不到会访问__index(t,k)方法,更新为__newindex(t,k,v)方法

    function 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. 新建对象
    lua
    function c:new(o)
    o = o or {}
    setmetatable(o,c)
    return o
    end

继承

SpecialAccount = Account:new()
s = SpecialAccount:new{limit=1000.00}
-- 多重继承
function createClass(...)
    local c = {}
    setmetatable(c, {__index=function(t,k) return search(k,arg) end })
end

weak表

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

collectgarbage()

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

函数工厂

function newzxx(xxx):
    local f = functionxx
    return {f=f}
end

解析

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位置结束

table.getn -- memory search
table.setn
table.insert(a,x) -- push
table.remove(a) -- pop
table.insert(a,1,x), table.remove(a,1)
table.sort

string

string.len(s)
string.rep(s,n) -- repeat s for n times
string.lower(s) -- upper
string.sub(s,i,j) -- begin with 1. end as -1
i, j = string.find(s, "hello", [beg pos])
s, count = string.gsub(ori, mod, replace[, time])

IO

简单模式/完全模式

io.input(filename), io.output(filename)
io.read() -- a line
io.read(*all)
io.read(*number)
io.read(*line)
io.read(*num) --  char num
io.read(0) -- whether EOF
io.write("",math.sin(3),"")

f = assert(io.open("xxx.xxx", "r"))
local lines, rest = f:read(BUFISIZE,"*line")
outf:flush

os

os.time(year=x, month=x, day=x)
<-->
os.date("*t",1233)

debug

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

useful functions

string.format(fmt.."%q", unpack(arg), "1234")
table.sort(tb1, function(a,b) return (a.name>b.name) end)
io.read(*all)
阅读更多
想对作者说点什么? 我来说一句

Programming in Lua 4th Edition带书签

2017年09月19日 1.16MB 下载

Programming in Lua(4th) 无水印pdf

2017年09月27日 1.36MB 下载

Programming in Lua, 4th Edition

2017年06月15日 1.33MB 下载

Lua Programming Gems 高清书签

2017年11月17日 1.64MB 下载

Programming in Lua 4th Edition带目录

2017年08月21日 1.39MB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭