首页 > 技术文章 > Lua快速入门

hanschen-coder 2016-08-30 16:52 原文

转载请标明出处:http://blog.csdn.net/shensky711/article/details/52370850
本文出自: 【HansChen的博客】

什么是Lua

Lua 是一门强大、快速、轻量的嵌入式脚本语言。它由巴西里约热内卢 Pontifical Catholic 大学的 PUC-Rio 团队 开发。 Lua 是一个 自由软件, 广泛应用于世界上无数产品和项目

应用场景:

  • 游戏开发
  • 独立应用脚本
  • Web 应用脚本
  • 扩展和数据库插件如:MySQL Proxy 和 MySQL WorkBench
  • 安全系统,如入侵检测系统

基本语法

注释

  • 单行注释:两个减号是单行注释
  • 多行注释:
-- 这是一个单行注释

--[[
 多行注释
 多行注释
 --]]

标识符

Lua表示符用于定义一个变量,函数获取其他用户定义的项。标示符以一个字母 A 到 Z 或 a 到 z 或下划线 _ 开头后加上0个或多个字母、下划线、数字(0到9)。最好不要使用下划线加大写字母的标示符,因为Lua的保留字也是这样的。Lua 不允许使用特殊字符如 @, $, 和 % 来定义标示符。 Lua 是一个区分大小写的编程语言。因此在 Lua 中 W3c 与 w3c 是两个不同的标示符

关键字

 and       break     do          else      elseif    end
 false     for       function    goto      if        in
 local     nil       not         or        repeat    return
 then      true      until       while

数据类型

  • nil:只有值nil属于该类,表示一个无效值(在条件表达式中相当于false)
  • boolean:包含两个值:false和true
  • number:有两种内部表现方式,整数和浮点数。标准Lua使用 64 位整数和双精度
    (64位)浮点数
  • string:string表示一个不可变的字节序列,由一对双引号或单引号来表示
  • function:由C或Lua编写的函数
  • userdata:表示任意存储在变量中的C数据结构
  • thread:表示执行的独立线路,用于执行协同程序
  • table:Lua 中的表(table)其实是一个”关联数组”(associative arrays),这个数组不仅仅以数字做索引,除了nil和NaN之外的所有Lua值都可以做索引。 (Not a Number是一个特殊的数字,它用于表示未定义或表示不了的运算结果,比如 0/0),也就是说,表内可以包含任何类型的值( nil 除外)。任何键的值若为nil 就不会被记入表结构内部。table的创建是通过”构造表达式”来完成,最简单构造表达式是{},用来创建一个空表

表、函数、线程、以及完全用户数据在 Lua 中被称为 对象: 变量并不真的持有 它们的值,而仅保存了对这些对象的引用。赋值、参数传递、函数返回,都是针对引用而不是针对值的操作

我们可以使用type函数测试给定变量或者值的类型:

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

变量

变量类型

Lua 变量有三种类型:全局变量、局部变量、表中的域

除非用local显示声明为局部变量,否则Lua中的变量全是全局变量,哪怕是语句块或是函数里。
局部变量的作用域为从声明位置开始到所在语句块结束。
变量的默认值均为 nil。

应该尽可能的使用局部变量,有两个好处:

  • 避免命名冲突
  • 访问局部变量的速度比全局变量更快
-- 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

赋值语句

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

a = "hello" .. "world" --字符串拼接
t.n = t.n + 1

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

a, b = 10, 2*x       <-->       a=10; b=2*x

遇到赋值语句Lua会先计算右边所有的值然后再执行赋值操作,所以我们可以这样进行交换变量的值:

x, y = y, x                     -- swap 'x' for 'y'
a[i], a[j] = a[j], a[i]         -- swap 'a[i]' for 'a[j]'

当变量个数和值的个数不一致时,Lua会一直以变量个数为基础采取以下策略:

  • 变量个数 > 值的个数: 按变量个数补足nil
  • 变量个数 < 值的个数: 多余的值会被忽略
a, b, c = 0, 1
print(a,b,c)             --> 0   1   nil

a, b = a+1, b+1, b+2     -- value of b+2 is ignored
print(a,b)               --> 1   2

a, b, c = 0
print(a,b,c)             --> 0   nil   nil

多值赋值经常用来交换变量,或将函数调用返回给变量:

a, b = f()     -- f()返回两个值,第一个赋给a,第二个赋给b

循环

while

基本语法:

while(condition)
do
   statements
end

-- 举例
a=10
while( a < 20 )
do
   print("a 的值为:", a)
   a = a+1
end

for循环

数值for循环:

-- var从exp1变化到exp2,每次变化以exp3为步长递增var,并执行一次"执行体"。exp3是可选的,如果不指定,默认为1
for var=exp1,exp2,exp3 do  
    <执行体>  
end 

--举例
for i=1, f(5) do --f(x)只在循环开始前求值一次
    print(i)
end

for i=10, 1, -1 do
    print(i)
end

泛型for循环

for K, v in pairs/ipairs(table) do
    print(v) 
end 

根据官方手册的描述,pairs会遍历表中所有的key-value值,而ipairs会根据key的数值从1开始加1递增遍历对应的table[i]值,直到table[i]的值是nil的时候就退出。

stars = {[1] = "Sun", [2] = "Moon", [5] = 'Earth'}

for i, v in pairs(stars) do
   print(i, v)
end
--[[
输出:
1    Sun
2    Moon
5    Earth
 --]]

 for i, v in ipairs(stars) do
   print(i, v)
end
--[[
输出:
1    Sun
2    Moon
因为stars[3]是nil
 --]]

repeat…until 循环

repeat…until 是条件后行,所以repeat…until 的循环体里面至少要运行一次
基本语法:

repeat
   statements
while( condition )
--[ 变量定义 --]
a = 10
--[ 执行循环 --]
repeat
   print("a的值为:", a)
   a = a + 1
until( a > 15 )

输出结果

a的值为:   10
a的值为:   11
a的值为:   12
a的值为:   13
a的值为:   14
a的值为:   15

流程控制

基本语法:

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

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

elseif( 布尔表达式 3)
then
   --[ 在布尔表达式 3true 时执行该语句块 --]
else 
   --[ 如果以上布尔表达式都不为 true 则执行该语句块 --]
end

函数

基本使用

在Lua中,函数是对语句和表达式进行抽象的主要方法。既可以用来处理一些特殊的工作,也可以用来计算一些值。

Lua 函数主要有两种用途:

  • 完成指定的任务,这种情况下函数作为调用语句使用
  • 计算并返回值,这种情况下函数作为赋值语句的表达式使用

Lua 编程语言函数定义格式如下:

optional_function_scope function function_name( argument1, argument2, argument3..., argumentn)
    function_body
    return result_params_comma_separated
end
  • optional_function_scope:该参数是可选的制定函数是全局函数还是局部函数,未设置该参数末尾为全局函数,如果你需要设置函数为局部函数需要使用关键字 local
  • function_name:函数名称
  • 函数参数:多个参数以逗号隔开,函数也可以不带参数
  • 函数返回值:Lua语言函数可以返回多个值,每个值以逗号隔开

Lua中,函数是first class,我们可以将函数作为参数传递给函数,如下实例:

myprint = function(param)
   print("这是打印函数 -   ##",param,"##")
end

function add(num1,num2,functionPrint)
   result = num1 + num2
   -- 调用传递的函数参数
   functionPrint(result)
end

-- myprint 函数作为参数传递
add(2,5,myprint)

多返回值

Lua函数中,在return后列出要返回的值得列表即可返回多值,如:

function maximum (a)
    local mi = 1             -- 最大值索引
    local m = a[mi]          -- 最大值
    for i,val in ipairs(a) do
       if val > m then
           mi = i
           m = val
       end
    end
    return m, mi
end

value, key = maximum({8,10,23,12,5})
print(key) --输出3
print(value) --输出23

可变参数

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

Lua将函数的参数放在一个叫arg的表中,#arg 表示传入参数的个数
例如,我们计算几个数的平均值:

function average(...)
   result = 0
   for i,v in ipairs(arg) do
      result = result + v
   end
   print("总共传入 " .. #arg .. " 个数")
   return result/#arg
end

print("平均值为: ",average(10,5,3,4,5,6))

运算符

算术运算符

image_1arcmmj32ich15tbi15ht016ko9.png-28kB

关系运算符

image_1arcmnu3be3q1nk71nfo1d1ls24m.png-39.8kB

逻辑运算符

image_1arcmp39u3e012rs8bu1vk3vfe13.png-26.5kB

其他运算符

image_1arcmpptot0s1a611bqd13s21b431g.png-18.5kB

运算符优先级

^
not    - (unary)
*      /
+      -
..
<      >      <=     >=     ~=     ==
and
or

table

不同于其他语言的数组把 0 作为数组的初始索引,在 Lua 里表的默认初始索引一般以 1 开始
在 Lua 里,table 的创建是通过”构造表达式”来完成,最简单构造表达式是{},用来创建一个空表。也可以在表里添加一些数据,直接初始化表:

-- 创建一个空的 table
local tbl1 = {}

-- 直接初始表
local tbl2 = {"apple", "pear", "orange", "grape"}

-- 初始化的时候设置key,注意,key不需要带引号,且初始化的时候不能以数字作为key
local tbl2 = {apple = "apple", pear = "pear", orange = "orange", grape = "grape"}

--可以通过table[i]、table['key']、table.key的方式访问数据

Lua 中的表(table)其实是一个”关联数组”(associative arrays),数组的索引可以是数字或者是字符串:

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

推荐阅读