• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Lua-简洁、轻量、可扩展的脚本语言

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

转自:http://rmingwang.com/The-Programming-Language-Lua.html

 

1. 一、Lua安装及常用库的安装

2. 1.1 Ubuntu

  1. $ sudo apt-get install lua5.2

3. 1.2 OS X

  1. $ brew install lua luarocks # luarocks是lua的模块管理工具
  2. $ sudo ln -s /usr/bin/make /usr/bin/gmake # 解决 sh: gmake: command not found

4. 1.3 luasocket库的安装

  1. $ luarocks install luasocket
  2. $ lua
  3. > socket = require("socket")
  4. > print(socket._VERSION)
  5. LuaSocket 2.0.2

5. 1.4 lua-cjson库的安装

  1. $ luarocks install lua-cjson
  2. $ lua
  3. > cjson = require("cjson")
  4. > print(cjson.encode({ name = "linguofeng" }))
  5. {"name":"linguofeng"}

6. 二、HelloWorld

  1. $ lua
  2. > print("Hello World!!")
  3. Hello World!!

7. 三、数据类型 有8种基本数据类型

  1. 类型 说明
  2. nil 全局变量默认值,如果要删除一个全局变量可以赋值为nil
  3. boolean 布尔值
  4. number 数字型
  5. string 字符串型
  6. userdata 用户自定义类型,一般是C/C++中的类型
  7. function 函数
  8. thread 线程
  9. table
  10. print(type(nil)) -- 输出 nil
  11. print(type(99.7+12*9)) -- 输出 number
  12. print(type(true)) -- 输出 boolean
  13. print(type("Hello Wikipedia")) -- 输出 string
  14. print(type(print)) -- 输出 function
  15. print(type{1, 2, test = "test"}) -- 输出 table

8. 四、函数 第一类值

第一类值指:在Lua中函数和其他值(数值、字符串)一样,函数可以被存放在变量中,也可以存放在表中,可以作为函数的参数,还可以作为函数的返回值。

  1. function add(x, y) -- 定义一个函数add,并接收两个参数
  2. local a = x + y -- 定义一个局部变量a,接收x+y的和,局部变量仅在函数add中有效
  3. return a -- 返回
  4. end -- 结束add函数
  5. print("15 + 64 = " .. add(15, 64)); -- 打印add(15, 64)的结果
  6. local x = 1 -- local 关键字表示该变量为局部变量,作用域为当前上下文
  7. -- 无该关键字修饰时为全局变量,作用于整个Lua状态机
  8. local add = function(x, y) -- 局部函数,作用于当前脚本(chumk
  9. Lib = {}
  10. Lib.add = function(x, y) -- 表函数,作用于Lib

9. 函数闭包

闭包是一个内部函数以及它的upvalues,内部函数使用了外部(父函数)局部变量。

  1. function newCounter()
  2. local i = 0 -- i为匿名函数的外部局部变量(upvalue
  3. return function() -- 匿名内部函数
  4. i = i + 1 -- 使用了i,所以该匿名函数是一个闭包
  5. return i
  6. end
  7. end
  8. c1 = newCounter() -- 得到一个匿名函数的变量(闭包)
  9. print(c1()) -- 调用匿名函数,打印出1
  10. print(c1()) -- 调用匿名函数,打印出2
  11. c2 = newCounter()
  12. print(c2()) --> 1
  13. print(c1()) --> 3
  14. print(c2()) --> 2

10. 五、控制语句

  1. for int i = 0, 10, 2 do -- for循环,2表示步长,省略时为1
  2. print("i = " .. i) -- .. 表示字符串连接符
  3. end -- 结束for
  4. if a > b then -- if条件判断语句
  5. print("a > b")
  6. else
  7. print("b > a")
  8. end
  9. while a > b do -- while循环
  10. print("")
  11. end
  12. repeat -- repeat-until循环
  13. print("")
  14. until a > b

11. 六、逻辑运算符 and、or、not

逻辑运算符认为false和nil是假(false),其他为真,0也是true.

  1. a and b -- 如果afalse,则返回a,否则返回b
  2. a or b -- 如果atrue,则返回a,否则返回b
  3. x = x or v -- 如果xfalse或者nil时则给x赋初始值v
  4. -- 等价于
  5. if not x then
  6. x = v
  7. end
  8. -- 三元运算符
  9. a ? b : c => a and b or c -- and 的优先级别比 or
  10. not -- not 的结果只返回falsetrue,作用类似于"非" "!"取反的意思
  11. print(not nil) -- true
  12. print(not false) -- true
  13. print(not 0) -- false

12. 七、协同程序 coroutine

7.1 创建协同

  1. co = coroutine.create(function () -- 创建一个协同函数,接收一个匿名函数,返回thread类型
  2. print("hi")
  3. end)
  4. print(co) -- thread: 0x7fe1834127d0

7.2 协同的三个状态:挂起态(suspended)、运行态(running)、停止态(dead)。

  1. print(coroutine.status(co)) -- 查看协同的状态,默认状态是挂起态 suspended
  2. coroutine.resume(co) -- 改变协同的状态为运行太 hi
  3. print(coroutine.status(co)) -- 协同运行完以后将变量停止态 dead

7.3 如此挂起正在运行的协同

  1. co = coroutine.create(function ()
  2. print("hi")
  3. coroutine.yield() -- 协同运行到此状态将变成挂起
  4. print("你好")
  5. end)
  6. coroutine.resume(co) -- hi
  7. coroutine.resume(co) -- 你好
  8. coroutine.resume(co) -- false,协同结束后将不能再使用

7.4 协同数据交换

  1. co = coroutine.create(function (x, y) -- 接收两个参数
  2. print("hi", coroutine.yield(x + y)) -- 返回一个值,同时参数也传递给了coroutine.yield
  3. return 100 -- 第三种返回值的方式
  4. end)
  5. print(coroutine.resume(co, 12, 87)) -- 传递两个参数并接收返回值(true, 99)
  6. -- 执行coroutine.yield(x + y)之前协同被挂起,但值被返回,因此print函数未被执行,下面执行
  7. print(coroutine.resume(co, 12, 87)) -- 传递两个参数并接收返回值(true, 100)

13. 八、数据结构 table

8.1 表的创建

  1. arrays = {} -- 创建一个空表
  2. arrays[1] = "abc" -- 第一个索引值为1
  3. arrays[2] = 123
  4. arrays["key"] = "value" -- map
  5. for key, value in pairs(arrays) do -- 迭代table
  6. print(key .. " = " .. value)
  7. end

8.2 表的增删改查

  1. list = {123} -- 初始化表
  2. list[2] = "abc" --
  3. list.x = 123
  4. list.y = 987
  5. list[1] = nil --
  6. list.y = nil
  7. list[2] = 456 --
  8. list.x = 987
  9. print(list[2]) --
  10. print(list.x)
  11. print(list['x'])

8.3 数组

  1. list = {} -- 初始空化数组,数组的下标是整数,遵循Lua的标准,下标从1开始
  2. list[1] = "abc"
  3. list[2] = "edg"
  4. list[3] = "hij"

8.4 矩阵(二维数组)

  1. mt = {} -- 创建矩阵matrix
  2. for i = 1, N do -- 创建N
  3. mt[i] = {} -- 每行都是一个数组(table元素)
  4. for j = 1, M do -- 创建M
  5. mt[i][j] = "a" -- N行第M行的值
  6. end
  7. end

8.5 链表

  1. Singly-linked-list.svg
  2. list = nil
  3. list = {next = list, value = "hello3"}
  4. list = {next = list, value = "hello2"}
  5. list = {next = list, value = "hello1"}
  6. -- 遍历
  7. local l = list
  8. while l do
  9. print(l.value)
  10. l = l.next
  11. end

14. 九、metatable 元表

9.1 元表与元方法

元表也是普通表

  1. t = {}
  2. print(getmetatable(t)) -- 获取表的metatable nil,默认不带
  3. mt = {}
  4. setmetatable(t, mt) -- 设置一个元素
  5. -- metamethod 元表的方法(元方法)
  6. mt.__add -- +
  7. mt.__sub -- -
  8. mt.__mul -- *
  9. mt.__div -- /
  10. mt.__unm -- -
  11. mt.__pow -- ^
  12. mt.__concat -- 连接
  13. mt.__eq -- 等于 =
  14. mt.__lt -- 小于 <
  15. mt.__le -- 大于 >
  16. mt.__tostring -- print调用
  17. mt.__metatable -- 设置该元表不被修改与访问
  18. mt.__index -- 当访问不存在的元素时会去查询,相当于子类继承父类一样
  19. mt.__newindex -- 更新表,如果增加一个不存在的元素,会去查询,有直接用,否则增加

9.2 表的代理

记录下表的增查记录

  1. local index = {} -- 私有的key,用来记录原始表在代理表中的下标
  2. local mt = { -- 创建元表
  3. __index = function(t, k)
  4. print("访问了" .. tostring(k) .. "元素")
  5. return t[index][k] -- 从代理表中获取原始表中k下标的数据
  6. end,
  7. __newindex = function(t, k, v)
  8. print("更新了 " .. tostring(k) .. " 元素的值为 " .. tostring(v))
  9. t[index][k] = v -- 更新代理表中下标为index的原始表中的元素
  10. end
  11. }
  12. function setProxy(t)
  13. local proxy = {} -- 创建代理表
  14. proxy[index] = t -- 把原始表加到代理表的index下标中
  15. setmetatable(proxy, mt) -- 设置代理表的元表
  16. return proxy -- 返回代理表,即所有操作都是直接操作代理表
  17. end
  18. p = setProxy({})
  19. p[2] = 'abcdefg' -- 更新了 2 元素的值为 abcdefg
  20. print(p[2]) -- 访问了2元素

15. 十、环境

10.1 全局变量 _G

  1. > _G["ewgegw"] = "ddddddgege"
  2. > table.foreach(_G, print)
  3. string table: 0x7ffce3407a60
  4. xpcall function: 0x7ffce3404780
  5. package table: 0x7ffce3405780
  6. tostring function: 0x7ffce3405020
  7. print function: 0x7ffce3405160
  8. os table: 0x7ffce34073e0
  9. unpack function: 0x7ffce34050d0
  10. ewgegw ddddddgege -- 上面添加的全局变量
  11. require function: 0x7ffce3405e70
  12. getfenv function: 0x7ffce3404db0
  13. setmetatable function: 0x7ffce3404f60
  14. next function: 0x7ffce3404d20
  15. assert function: 0x7ffce3404a80
  16. tonumber function: 0x7ffce3404fc0
  17. io table: 0x7ffce3406bd0
  18. rawequal function: 0x7ffce34051b0
  19. collectgarbage function: 0x7ffce3404ad0
  20. getmetatable function: 0x7ffce3404e00
  21. module function: 0x7ffce3405e20
  22. rawset function: 0x7ffce3405260
  23. math table: 0x7ffce3408290
  24. debug table: 0x7ffce3408c50
  25. pcall function: 0x7ffce3404d70
  26. table table: 0x7ffce3405f10
  27. newproxy function: 0x7ffce34052e0
  28. type function: 0x7ffce3405080
  29. coroutine table: 0x7ffce3405380 -- 对应的是协同的表
  30. _G table: 0x7ffce3404110
  31. select function: 0x7ffce3404ec0
  32. gcinfo function: 0x7ffce3404150
  33. pairs function: 0x7ffce34048c0
  34. rawget function: 0x7ffce3405210
  35. loadstring function: 0x7ffce3404cc0
  36. ipairs function: 0x7ffce3404830
  37. _VERSION Lua 5.1
  38. dofile function: 0x7ffce3404bd0
  39. setfenv function: 0x7ffce3404f10
  40. load function: 0x7ffce3404c70
  41. error function: 0x7ffce3404c20
  42. loadfile function: 0x7ffce3404e60
  43. > table.foreach(_G.os, print)

10.2 非全局变量 setfenv

  1. --pack.lua---------------------------------------------------------------------
  2. local P = {}
  3. -- 改变P表的__index,这里的_G代表全局环境
  4. setmetatable(P, {__index = _G})
  5. -- 改变当前的环境为P,setfenv前的所有定义都是在全局环境中进行的,后面的则都是在新环境中进行的,互不影响
  6. setfenv(1, P)
  7. -- 声明的add函数在环境P中,如果要在外部访问必须P.add
  8. function add(x, y)
  9. print(x

    鲜花

    握手

    雷人

    路过

    鸡蛋
    该文章已有0人参与评论

    请发表评论

    全部评论

    专题导读
    热门推荐
    热门话题
    阅读排行榜

    扫描微信二维码

    查看手机版网站

    随时了解更新最新资讯

    139-2527-9053

    在线客服(服务时间 9:00~18:00)

    在线QQ客服
    地址:深圳市南山区西丽大学城创智工业园
    电邮:jeky_zhao#qq.com
    移动电话:139-2527-9053

    Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap