参考文献

注释

单行注释

  • 两个减号是单行注释:
1
--

多行注释

1
2
3
4
--[[
多行注释
多行注释
--]]

关键词

  • 以下列出了 Lua的保留关键词.保留关键字不能作为常量或变量或其他用户自定义标示符:
and break do else
elseif end false for
function if in local
nil not or repeat
return then true until
while goto
  • 一般约定,以下划线开头连接一串大写字母的名字(比如 _VERSION)被保留用于 Lua内部全局变量.

数据类型

  • Lua是动态类型语言,变量不要类型定义,只需要为变量赋值. 值可以存储在变量中,作为参数传递或结果返回.
  • Lua中有 8 个基本类型分别为: nil、boolean、number、string、userdata、function、threadtable.
数据类型 描述
nil 这个最简单,只有值nil属于该类,表示一个无效值(在条件表达式中相当于false).
boolean 包含两个值: false和true.
number 表示双精度类型的实浮点数
string 字符串由一对双引号或单引号来表示
function 由 C 或 Lua编写的函数
userdata 表示任意存储在变量中的C数据结构
thread 表示执行的独立线路,用于执行协同程序
table Lua中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字、字符串或表类型.在 Lua里,table 的创建是通过"构造表达式"来完成,最简单构造表达式是{},用来创建一个空表.
1
2
3
4
5
6
7
print(type("Hello world"))      --> string
print(type(10.4*3)) --> number
print(type(print)) --> function
print(type(type)) --> function
print(type(true)) --> boolean
print(type(nil)) --> nil
print(type(type(X))) --> string

nil

  • nil作比较时应该加上双引号 "

    1
    2
    3
    4
    5
    6
    7
    > type(X)
    nil
    > type(X)==nil
    false
    > type(X)=="nil"
    true
    >
    • type(X)==nil结果为 false 的原因是 type(X) 实质是返回的 “nil” 字符串,是一个 string 类型

boolean

  • boolean 类型只有两个可选值: true(真) 和 false(假),Lua把 false 和 nil 看作是 false,其他的都为 true,数字 0 也是 true

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    print(type(true))
    print(type(false))
    print(type(nil))

    if false or nil then
    print("至少有一个是 true")
    else
    print("false 和 nil 都为 false")
    end

    if 0 then
    print("数字 0 是 true")
    else
    print("数字 0 为 false")
    end


    -- output
    boolean
    boolean
    nil
    falsenil 都为 false
    数字 0true

number

  • Lua默认只有一种 number 类型 – double(双精度)类型(默认类型可以修改 luaconf.h 里的定义),以下几种写法都被看作是 number 类型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    print(type(2))
    print(type(2.2))
    print(type(0.2))
    print(type(2e+1))
    print(type(0.2e-1))
    print(type(7.8263692594256e-06))

    -- output
    number
    number
    number
    number
    number
    number

string

  • 字符串由一对双引号或单引号来表示

    1
    2
    string1 = "this is string1"
    string2 = 'this is string2'
  • 也可以用 2 个方括号 “[[]]” 来表示"一块"字符串

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    html = [[
    <html>
    <head></head>
    <body>
    <a href="http://www.runoob.com/">菜鸟教程</a>
    </body>
    </html>
    ]]
    print(html)

    -- output
    <html>
    <head></head>
    <body>
    <a href="http://www.runoob.com/">菜鸟教程</a>
    </body>
    </html>
  • 在对一个数字字符串上进行算术操作时,Lua会尝试将这个数字字符串转成一个数字

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    > print("2" + 6)
    8.0
    > print("2" + "6")
    8.0
    > print("2 + 6")
    2 + 6
    > print("-2e2" * "6")
    -1200.0
    > print("error" + 1)
    stdin:1: attempt to perform arithmetic on a string value
    stack traceback:
    stdin:1: in main chunk
    [C]: in ?
    >
    • 以上代码中"error" + 1执行报错了,字符串连接使用的是..

      1
      2
      3
      4
      > print("a" .. 'b')
      ab
      > print(157 .. 428)
      157428
  • 使用 # 来计算字符串的长度,放在字符串前面

    1
    2
    3
    4
    5
    > len = "www.runoob.com"
    > print(#len)
    14
    > print(#"www.runoob.com")
    14

table

  • Lua里,table 的创建是通过"构造表达式"来完成,最简单构造表达式是{},用来创建一个空表.也可以在表里添加一些数据,直接初始化表

    1
    2
    3
    4
    5
    -- 创建一个空的 table
    local tbl1 = {}

    -- 直接初始表
    local tbl2 = {"apple", "pear", "orange", "grape"}
  • Lua中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字或者是字符串

    1
    2
    3
    4
    5
    6
    7
    8
    9
    -- table_test.lua脚本文件
    a = {}
    a["key"] = "value"
    key = 10
    a[key] = 22
    a[key] = a[key] + 11
    for k, v in pairs(a) do
    print(k .. " : " .. v)
    end
  • 不同于其他语言的数组把 0 作为数组的初始索引,在 Lua里表的默认初始索引一般以 1 开始

    1
    2
    3
    4
    5
    -- table_test2.lua脚本文件
    local tbl = {"apple", "pear", "orange", "grape"}
    for key, val in pairs(tbl) do
    print("Key", key)
    end
  • table 不会固定长度大小,有新数据添加时 table 长度会自动增长,没初始的 table 都是 nil

    1
    2
    3
    4
    5
    6
    7
    8
    -- table_test3.lua脚本文件
    a3 = {}
    for i = 1, 10 do
    a3[i] = i
    end
    a3["key"] = "val"
    print(a3["key"])
    print(a3["none"])

function

  • Lua中,函数是被看作是"第一类值(First-Class Value)",函数可以存在变量里

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    -- function_test.lua脚本文件
    function factorial1(n)
    if n == 0 then
    return 1
    else
    return n * factorial1(n - 1)
    end
    end
    print(factorial1(5))
    factorial2 = factorial1
    print(factorial2(5))
  • function 可以以匿名函数(anonymous function)的方式通过参数传递

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    -- function_test2.lua脚本文件
    function testFun(tab,fun)
    for k ,v in pairs(tab) do
    print(fun(k,v));
    end
    end


    tab={key1="val1",key2="val2"};
    testFun(tab,
    function(key,val)--匿名函数
    return key.."="..val;
    end
    );

变量

  • 变量在使用前,需要在代码中进行声明,即创建该变量.
  • 编译程序执行代码之前编译器需要知道如何给语句变量开辟存储区,用于存储变量的值.
  • Lua变量有三种类型: 全局变量、局部变量、表中的域.
  • Lua中的变量全是全局变量,哪怕是语句块或是函数里,除非用 local 显式声明为局部变量.
  • 局部变量的作用域为从声明位置开始到所在语句块结束.
  • 变量的默认值均为 nil.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-- test.`Lua`文件脚本
a = 5 -- 全局变量
local b = 5 -- 局部变量

function joke()
c = 5 -- 全局变量
local d = 6 -- 局部变量
end

joke()
print(c,d) --> 5 nil

do
local a = 6 -- 局部变量
b = 6 -- 对局部变量重新赋值
print(a,b); --> 6 6
end

print(a,b) --> 5 6

全局变量

  • 在默认情况下,变量总是认为是全局的.

  • 全局变量不需要声明,给一个变量赋值后即创建了这个全局变量,访问一个没有初始化的全局变量也不会出错,只不过得到的结果是: nil.

  • 如果你想删除一个全局变量,只需要将变量赋值为nil

    1
    2
    b = nil
    print(b) --> nil

赋值语句

  • 赋值是改变一个变量的值和改变表域的最基本的方法.

  • Lua可以对多个变量同时赋值,变量列表和值列表的各个元素用逗号分开,赋值语句右边的值会依次赋给左边的变量.

    1
    a, b = 10, 2*x    --   相当于       a=10; b=2*x
  • 遇到赋值语句Lua会先计算右边所有的值然后再执行赋值操作,所以我们可以这样进行交换变量的值:

    1
    2
    x, y = y, x                     -- swap 'x' for 'y'
    a[i], a[j] = a[j], a[i] -- swap 'a[i]' for 'a[j]'
  • 当变量个数和值的个数不一致时,Lua会一直以变量个数为基础采取以下策略

    • 变量个数 > 值的个数 按变量个数补足nil
    • 变量个数 < 值的个数 多余的值会被忽略

索引

  • 对 table 的索引使用方括号[].Lua也提供了.操作.
1
2
3
t[i]
t.i -- 当索引为字符串类型时的一种简化写法
gettable_event(t,i) -- 采用索引访问本质上是一个类似这样的函数调用

Lua循环

循环类型 描述
while 循环 在条件为 true 时,让程序重复地执行某些语句.执行语句前会先检查条件是否为 true.
for 循环 重复执行指定语句,重复次数可在 for 语句中控制.
repeat…until 重复执行循环,直到 指定的条件为真时为止
循环嵌套 可以在循环内嵌套一个或多个循环语句(while do … end;for … do … end;repeat … until;)
1
2
3
4
while(condition)
do
statements
end
1
2
3
for var=exp1,exp2,exp3 do  
<执行体>
end
1
2
3
repeat
statements
until( condition )

循环控制语句

控制语句 描述
break 语句 退出当前循环或语句,并开始脚本执行紧接着的语句.
goto 语句 将程序的控制点转移到一个标签处.

Lua流程控制

语句 描述
if 语句 if 语句 由一个布尔表达式作为条件判断,其后紧跟其他语句组成.
if…else 语句 if 语句 可以与 else 语句搭配使用, 在 if 条件表达式为 false 时执行 else 语句代码.
if 嵌套语句 你可以在ifelse if中使用一个或多个 ifelse if 语句 .
1
2
3
if 0 then
print("数字 0 是 true")
end
1
2
3
4
5
if 0 then
print("数字 0 是 true")
else
print("数字 0 为 false")
end

Lua函数

函数定义

1
2
3
4
optional_function_scope function function_name( argument1, argument2, argument3..., argumentn)
function_body
return result_params_comma_separated
end
  • optional_function_scope: 该参数是可选的指定函数是全局函数还是局部函数,未设置该参数默认为全局函数,如果你需要设置函数为局部函数需要使用关键字 local.
  • function_name: 指定函数名称.
  • argument1, argument2, argument3..., argumentn: 函数参数,多个参数以逗号隔开,函数也可以不带参数.
  • function_body: 函数体,函数中需要执行的代码语句块.
  • result_params_comma_separated: 函数返回值,Lua语言函数可以返回多个值,每个值以逗号隔开

示例

  • Lua中可以将函数作为参数传递给函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    myprint = function(param)
    print("这是打印函数 - ##",param,"##")
    end

    function add(num1,num2,functionPrint)
    result = num1 + num2
    -- 调用传递的函数参数
    functionPrint(result)
    end
    myprint(10)
    -- myprint 函数作为参数传递
    add(2,5,myprint)

可变参数

  • Lua函数可以接受可变数目的参数,和 C 语言类似,在函数参数列表中使用三点 表示函数有可变的参数.

    1
    2
    3
    4
    5
    6
    7
    8
    function add(...)  
    local s = 0
    for i, v in ipairs{...} do --> {...} 表示一个由所有变长参数构成的数组
    s = s + v
    end
    return s
    end
    print(add(3,4,5,6,7)) --->25
  • 可以通过 select("#",...) 来获取可变参数的数量

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function average(...)
    result = 0
    local arg={...}
    for i,v in ipairs(arg) do
    result = result + v
    end
    print("总共传入 " .. select("#",...) .. " 个数")
    return result/select("#",...)
    end

    print("平均值为",average(10,5,3,4,5,6))
    • 通常在遍历变长参数的时候只需要使用 {…},然而变长参数可能会包含一些 nil,那么就可以用 select 函数来访问变长参数了: select(‘#’, …) 或者 select(n, …)

      • select(‘#’, …) 返回可变参数的长度.
      • select(n, …) 用于返回从起点 n 开始到结束位置的所有参数列表.