[Lua系列]Lua入门,看这一篇就够了!

1,066 阅读5分钟

一、变量

  1. Lua 默认变量是全局变量,哪怕是语句块或是函数里,除非用 local声明为局部变量。
    • 尽可能的使用局部变量:避免命名冲突;访问局部变量的速度更快。
  2. 当一个变量不等于nil时,这个变量即存在。想删除一个全局变量,只需要将变量赋值为nil。
  3. Lua函数可以返回多个结果值,比如string.find,其返回匹配串"开始和结束的下标"(如果不存在匹配串返回nil)。
> b=10   -- 全局变量print(b)  
> 10  
---------
function joke()  
    c = 5           -- 全局变量  
    local d = 6     -- 局部变量  
end  
  
joke()  
print(c,d)          --> 5 nil
---------
> b=nilprint(b)  
> nil
--------
> s, e = string.find("www.runoob.com", "runoob") 
> print(s, e)
5    10

二、 数据类型

数据类型解释
nil只有一个值nil,表示无效。在逻辑判断中表示false 。
booleanfalse和true。
number双精度类型的实浮点数
string字符串由一对双引号或单引号来表示
function由 C 或 Lua 编写的函数
userdata表示任意存储在变量中的C数据结构
thread表示执行的独立线路,用于执行协同程序
table其实是一个"关联数组"(associative arrays)。数组的索引可以是数字、字符串或表类型。在 Lua 里,table 的创建是通过"构造表达式"来完成,最简单构造表达式是{},用来创建一个空表。

*type 函数可返回值的类型(print(type(print))      --> function)

nil

  • 做比较时,需要加上双引号 type(X)=="nil"

boolean

  • false 和 nil 是 false,其他的都为 true(数字 0 是 true):

number

  • 只有一种 number 类型 -- double(双精度)类型

string

  • 用单引号、双引号或两个方括号表示
string1 = "this is string1" -- 双引号
string2 = 'this is string2' -- 单引号
-------两个方括号-------
html = [[  
<html>  
<head></head>  
<body>  
    <a href="http://www.runoob.com/">菜鸟教程</a>  
</body>  
</html>  
]]  
print(html)
----结果如下-----
<html>
<head></head>
<body>
    <a href="http://www.runoob.com/">菜鸟教程</a>
</body>
</html>

对一个数字字符串上进行算术操作时,Lua 会尝试将数字字符串转成数字:

print("2" + 6)  
8.0

常用方法

----被替换的字符、要替换的字符、num 替换次数(可忽略--全部替换),
> string.gsub("aaaa","a","z",3); 
zzza    3
--- 字符串长度
>string.len("abc") 
3
 --- 字符串连接使用的是 ..
> print("a" .. 'b')
ab
----字符串截取----
>取字符串前缀,第1个到第8local second_sub = string.sub(sourcestr, 18)
>截取最后10local third_sub = string.sub(sourcestr, -10)

table

  • table是一个"关联数组",数组的索引可以是数字或者是字符串(不能是 nil)。
  • 默认初始索引以 1 开始。
  • 索引:table[i] 或 table.i
  • table a 设置元素,然后将 a 赋值给 b,则 a 与 b 都指向同一个内存。a 设置为 nil 后, b 还能访问 table 的元素。a的值更改后,b的值也会更改。
  • *pairs 和 ipairs的区别:
 - pairs迭代table,遍历table中所有元素
 - ipairs按照索引,从1开始递增遍历,遇到nil值停止
 --创建表
 local tbl1 = {}
 local tbl2 = {"apple""pear""orange""grape"}
 
 --遍历表
 a = {}
a["fanfan"] = "beauty"
a[2] = 3
for k, v in pairs(a) do
    print(k..":"..v)
end
--输出:
--  2:3
--  fanfan:beauty
b = {"apple", "pear", "orange", "grape"}
for key, val in pairs(b) do
    print("Key:", key)
end
--输出:
--  Key:	1
--  Key:	2
--  Key:	3
--  Key:	4

table常见操作

fruits = {"banana","orange","apple"}  
  
-- 在末尾插入  
table.insert(fruits,"mango")  
print("索引为 4 的元素为 ",fruits[4])  
--索引为 4 的元素为     mango

--移除元素 
table.remove(fruits)  
print("移除后最后一个元素为 ",fruits[4])
--移除后最后一个元素为     nil

--排序:从小到大
table.sort(fruits)

--table长度
function table_leng(t)
  local leng=0
  for k, v in pairs(t) do
    leng=leng+1
  end
  return leng;
end

--table最大值
function table_maxn(t)  
  local mn=nil;  
  for k, v in pairs(t) do  
    if(mn==nilthen  
      mn=v  
    end  
    if mn < v then  
      mn = v  
    end  
  end  
  return mn  
end

无状态的迭代器

无状态的迭代器: 不保留任何状态的迭代器,避免创建闭包花费额外的代价。

  • 每一次迭代,迭代函数都是用两个变量状态常量控制变量的值作为参数被调用,获取下一个元素。
  • 状态常量只在第一次时赋值
  • 返回值为nil,退出for循环;不是nil,返回值赋值给变量列表,并执行循环体
--state:状态常量
--control:控制变量
function square(state,control)
    if(control > state) then
        return nil
    else
        control = control + 1
        return control, control*control
    end
end

for i,j in square,9,0 do
    print(i,j)
end
-----结果-----
1	1
2	4
3	9
4	16
5	25
6	36
7	49
8	64
9	81
10	100

数组

--一维数组
array = {}  
  
for i= -22 do  
   array[i] = i *2  
end

--三维数组
  -- 初始化数组  
array = {}  
maxRows = 3  
maxColumns = 3  
for row=1,maxRows do  
   for col=1,maxColumns do  
      array[row*maxColumns +col] = row*col  
   end  
end  
  
  -- 访问数组  
for row=1,maxRows do  
   for col=1,maxColumns do  
      print(array[row*maxColumns +col])  
   end  
end


function

  • 函数可以存在变量里,也可以通过匿名函数的方式通过参数传递
  • 调用函数时,即使实参列表和形参列表不一致也能成功调用,多余的参数会被舍弃,缺少的参数会被补为 nil。
-- tab里的值,在fun中输出
function test(tab,fun)
    for k,v in pairs(tab) do
        print(fun(k,v));
    end
end

tab = {"apple", "pear"}
test(tab,
function(key,val)
    return key.."="..val;
end
);
        

可变参数

  • Lua 函数可以接受可变数目的参数,在函数参数列表中使用三点 ... 表示函数有可变的参数。
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

thread

  • Lua最主要的线程是协同程序(coroutine),拥有自己独立的栈、局部变量和指令指针,可以跟其他协同程序共享全局变量和其他大部分东西。
  • 线程跟协程的区别:线程可以同时多个运行,而协程任意时刻只能运行一个,并且处于运行状态的协程只有被挂起(suspend)时才会暂停。

userdata(自定义类型)

  • 用户自定义数据,用于表示一种由应用程序或 C/C++ 语言库所创建的类型,可以将任意 C/C++ 的任意数据类型的数据(通常是 struct 和 指针)存储到 Lua 变量中调用。

三、 语法

赋值

x, y = y, x  -- 交换

条件循环语句

if...else

if(布尔表达式)
then
   --[ 布尔表达式为 true 时执行该语句块 --]
else
   --[ 布尔表达式为 false 时执行该语句块 --]
end

if...else if...else

if( 布尔表达式 1)
then
   --[ 在布尔表达式 1 为 true 时执行该语句块 --]

elseif( 布尔表达式 2)
then
   --[ 在布尔表达式 2 为 true 时执行该语句块 --]
end

while

while(condition)
do
   statements
   if( a > 15)
     then
        --[ 使用 break 语句终止循环 --]
        break
     end
end

for

for var=exp1,exp2,exp3 do  
    <执行体>  
end