Lua脚本

1.准备

1.简介

  • 1.Lua是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放

2.目标

  • 1.其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能

3.特点

  • 1.轻量级:用标准C语言编写并以源代码形式开放,编译后仅仅一百余K,可方便嵌入别的程序里
  • 2.可扩展:Lua提供易于使用的扩展接口和机制:由宿主语言(C/C++)提供这些功能,Lua可像内置功能一样使用
  • 3.支持面向过程(procedure-oriented)编程和函数式编程(functional programming)
  • 4.自动内存管理,只提供了一种通用类型的表(table),用它可以实现数组,哈希表,集合,对象
  • 5.语言内置模式匹配;闭包(closure);函数也可以看做一个值;提供多线程(协同进程,并非操作系统所支持的线程)支持
  • 6.通过闭包和table可以很方便地支持面向对象编程所需要的一些关键机制,比如数据抽象,虚函数,继承和重载等

4.应用场景

  • 1.游戏开发
  • 2.独立应用脚本
  • 3.Web应用脚本
  • 4.扩展和数据库插件(MySQL ProxyMySQL WorkBench
  • 5.安全系统(入侵检测系统)

5.环境安装

1.Linux系统
bash 复制代码
curl -R -O http://www.lua.org/ftp/lua-5.3.0.tar.gz
tar zxf lua-5.3.0.tar.gz
cd lua-5.3.0
make linux test
make install
2.Mac系统
bash 复制代码
curl -R -O http://www.lua.org/ftp/lua-5.3.0.tar.gz
tar zxf lua-5.3.0.tar.gz
cd lua-5.3.0
make macosx test
make install
3.Window系统
  • 1.进入Lua官网:http://www.lua.org
  • 2.点击download
  • 3.选择二进制文件
  • 4.点击左边的Download并选择对应版本lua-5.4.2_Win64_bin.zip进行下载

  • 5.将对应压缩包解压到指定文件
  • 6.配置环境变量
  • 7.进入cmd进行测试

2.基础

1.交互式编程

  • 1.默认使用交互式编程
  • 2.交互式编程可以输入程序并立即查看结果

2.脚本式编程

  • 1.将Lua程序保存到一个以lua结尾的文件并执行
  • 2.如果Lua脚本文件有错误则内容都不会执行

3.注释

1.单行注释
lua 复制代码
--print("Hello World")
print("Hello Lua")


2.多行注释
lua 复制代码
--[[
多行注释
多行注释
--]]


4.标示符

  • 1.Lua标示符用于定义一个变量,函数获取其他用户定义的项
  • 2.标示符以一个字母 A-Za-z 或下划线 _ 开头,然后加上 0 个或多个字母,下划线,数字(0-9
  • 3.Lua不允许使用特殊字符( @$% )定义标示符
  • 4.不推荐使用下划线加大写字母的标示符,因为Lua的保留字也是这样
  • 5.一般约定以下划线开头连接一串大写字母的名字( _VERSION)被保留用于Lua内部全局变量
  • 6.Lua是一个区分大小写的编程语言,因此LuaRunoobrunoob是两个不同的标示符

5.关键字

  • 1.Lua保留关键字不能作为常量变量其他用户自定义标示符

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

6.全局变量

  • 1.默认情况下,变量总是认为是全局的
  • 2.全局变量不需要声明,给一个变量赋值后即创建了这个全局变量
  • 3.访问一个没有初始化的全局变量不会出错,只是得到的结果是nil
  • 4.如果想删除一个全局变量,只需要将变量赋值为nil;当且仅当一个变量不等于nil时,这个变量即存在

3.数据类型

  • 1.Lua是动态类型语言,变量不要类型定义,只需要为变量赋值

  • 2.值可以存储在变量中,作为参数传递或结果返回

  • 3.Lua可以使用type函数测试给定变量或者值的类型

  • 4.Lua中有8个基本类型

    数据类型 描述
    nil 只有值nil属于该类,表示一个无效值(在条件表达式中相当于false
    boolean falsetrue
    number 表示双精度类型的实浮点数
    string 字符串由一对双引号或单引号来表示
    function CLua编写的函数
    userdata 表示任意存储在变量中的C数据结构
    thread 表示执行的独立线路,用于执行协同程序
    table Lua中的表table其实是一个关联数组associative arrays;数组的索引可以是数字、字符串或表类型;Luatable 的创建是通过构造表达式来完成,最简单构造表达式是{},用来创建一个空表

1.nil(空)

  • 1.nil类型表示没有任何有效值,它只有一个值nil

  • 2.打印一个没有赋值的变量,便会输出一个nil

  • 3.对于全局变量和tablenil还有一个删除作用,将全局变量或table表里的变量赋nil值等同于删除

  • 4.nil作比较时应该加上双引号(type(X)==nil 结果为 false 的原因是 type(X) 实质是返回的nil字符串是一个 string 类型)



2.boolean(布尔)

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

3.number(数字)

  • 1.Lua默认只有一种number类型 -> double(双精度)类型(默认类型可以修改luaconf.h里的定义)

4.string(字符串)

  • 1.字符串由一对双引号或单引号来表示
  • 2.或者使用2个方括号[[]]来表示一块字符串
  • 3.对一个数字字符串进行算术操作时,Lua会尝试将该数字字符串转换成一个数字
  • 4.字符串连接使用的是 ..
  • 5.使用#计算字符串的长度并且放在字符串前面

5.table(表)

  • 1.Luatable的创建是通过构造表达式来完成,最简单构造表达式是{},用来创建一个空表
  • 2.table也可以创建时在表里添加数据直接初始化表
  • 3.Lua中的表table其实是一个关联数组associative arrays,数组的索引可以是数字字符串(表类似集合)
  • 4.如果遍历则第一个参数默认为索引,第二个参数为value
  • 5.不同于其他语言的数组把0作为数组的初始索引,Lua 中表的默认初始索引以1开始
  • 6.table不会固定长度大小,有新数据添加时table长度会自动增长(注意:#只能统计索引为数字的长度),没初始的table都是nil







6.function(函数)

  • 1.Lua中函数被看作是第一类值First-Class Value,函数可以存在变量中
  • 2.function可以以匿名函数anonymous function的方式通过参数传递



7.thread(线程)

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

8.userdata(自定义类型)

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

4.变量

  • 1.变量在使用前需要在代码中进行声明,即创建该变量
  • 2.编译程序执行代码之前编译器需要知道如何给语句变量开辟存储区,其用于存储变量的值
  • 3.Lua变量有三种类型
    • 1.全局变量
    • 2.局部变量
    • 3.表中的域
  • 4.变量的默认值均为nil

1.全局变量

  • 1.Lua中的变量全是全局变量,哪怕是语句块或是函数里,除非用local显式声明为局部变量
  • 2.Lua语言中,全局变量无须声明即可使用,使用未经初始化的全局变量不会导致错误
  • 3.当使用未经初始化的全局变量时,得到的结果为nil

2.局部变量

  • 1.只有使用local显式声明的才是局部变量
  • 2.局部变量的作用域为从声明位置开始到所在语句块结束
  • 3.尽可能的使用局部变量,有两个好处
    • 1.避免命名冲突
    • 2.访问局部变量的速度比全局变量更快

3.变量赋值

  • 1.Lua可对多个变量同时赋值,变量列表和值列表的各个元素用逗号分开,赋值语句右边的值会依次赋给左边的变量
  • 2.遇到赋值语句Lua会先计算右边所有的值然后再执行赋值操作,所以可以快捷交换变量的值
  • 3.当变量个数和值的个数不一致时,Lua会一直以变量个数为基础采取以下策略
    • 1.变量个数 > 值的个数 -> 按变量个数补足nil
    • 2.变量个数 < 值的个数 -> 多余的值会被忽略
  • 4.如果要对多个变量赋值必须依次对每个变量赋值
  • 5.多值赋值经常用来交换变量,或将函数调用返回给变量
  • 6.Lua对多个变量同时赋值,不会进行变量传递,仅做值传递




5.循环

  • 1.循环结构是在一定条件下反复执行某段程序的流程结构,被反复执行的程序被称为循环体
  • 2.循环语句是由循环体及循环的终止条件两部分组成的

1.while循环

lua 复制代码
while(condition)
do
  statements
end
  • 1.Luawhile循环语句在判断条件为true时会重复执行循环体语句
  • 2.statements(循环体语句) 可以是一条或多条语句,condition(条件) 可以是任意表达式,当 condition(条件) 为true时执行循环体语句

2.for循环

  • 1.Luafor循环语句可以重复执行指定语句,重复次数可在for语句中控制
  • 2.Lua编程语言中for语句有两大类
    • 1.数值for循环
    • 2.泛型for循环
1.数值for循环
lua 复制代码
for var=exp1,exp2,exp3 do  
	<执行体>  
end  
  • 1.varexp1变化到exp2,每次变化以exp3为步长递增var,并执行一次 执行体
  • 2.其中exp3是可选的,如果不指定则默认值为1
  • 3.for的三个表达式在循环开始前一次性求值(例:函数f(x)只在循环开始前执行一次),以后不再进行求值

2.泛型for循环
lua 复制代码
--打印数组a的所有值  
a = {"one", "two", "three"}
for i, v in ipairs(a) do
   print(i, v)
end 
  • 1.泛型for循环通过一个迭代器函数来遍历所有值,类似java中的foreach语句
  • 2.i是数组索引值,v是对应索引的数组元素值。ipairsLua提供的一个迭代器函数,用来迭代数组

3.repeat...until循环

lua 复制代码
repeat
  statements
until( condition )
  • 1.Luarepeat...until循环语句不同于forwhile循环
  • 2.forwhile循环的条件语句在当前循环执行开始时判断,而 repeat...until循环的条件语句在当前循环结束后判断
  • 3.因为循环条件判断语句condition在循环体末尾部分,所以在条件进行判断前循环体都会执行一次
  • 4.如果条件判断语句conditionfalse,循环会重新开始执行,直到条件判断语句conditiontrue才会停止执行

4.嵌套循环

lua 复制代码
for init,max/min value, increment
do
  for init,max/min value, increment
  do
     statements
  end
  statements
end
lua 复制代码
while(condition)
do
  while(condition)
  do
     statements
  end
  statements
end
lua 复制代码
repeat
  statements
  repeat
     statements
  until( condition )
until( condition )


5.break语句

  • 1.Luabreak语句插入在循环体中,用于退出当前循环或语句,并开始执行紧接着的语句
  • 2.如果你使用循环嵌套,break语句将停止最内层循环的执行,并开始执行的外层的循环语句

6.goto语句

lua 复制代码
goto Label

-- Label 的格式
:: Label ::
  • 1.Lua中的goto语句允许将控制流程无条件地转到被标记的语句处
  • 2.lable中可以设置多个语句
  • 3.使用goto可以实现continue的功能

6.流程控制

  • 1.Lua控制语句通过程序设定一个或多个条件语句,条件为true时执行指定程序代码,条件为false时执行其他指定代码
  • 2.控制结构的条件表达式结果可以是任何值,Lua认为falsenil为假,true和非nil为真,且Lua0true

1.if语句

2.if...else语句

3.if 嵌套语句

模块与包

  • 1.模块类似于一个封装库,从Lua 5.1开始Lua加入了标准的模块管理机制
  • 2.模块可把一些公用的代码放在一个文件里,以API接口的形式在其他地方调用,有利于代码的重用和降低代码耦合度
  • 3.Lua的模块是由变量、函数等已知元素组成的table
  • 4.因此创建一个模块很简单,就是创建一个table,然后把需要导出的常量、函数放入其中,最后返回这个table就行
  • 5.模块的结构就是一个table的结构,因此可以像操作调用table里的元素那样来操作调用模块里的常量或函数
  • 6.可使用local声明变量为程序块的局部变量,即表示一个私有函数,因此是不能从外部访问模块里的这个私有函数,必须通过模块里的公有函数来调用

1.require函数

  • 1.Lua提供了一个require的函数用来加载模块
  • 2.执行require后会返回一个由模块常量或函数组成的table,并且还会定义一个包含该table的全局变量
  • 3.其中require中引用的是Lua的文件名,而不是模块名,全局变量引用的是模块名,而不是文件名
  • 4.可以加载的模块定义一个别名变量方便调用


3.加载机制

  • 1.对于自定义的模块,模块文件不是放在哪个文件目录都行,函数 require 有自己的文件路径加载策略
  • 2.其会尝试从Lua文件或C程序库中加载模块
  • 3.require用于搜索Lua文件的路径是存放在全局变量package.path
  • 4.当Lua启动后会以环境变量LUA_PATH的值来初始这个环境变量
  • 5.如果没有找到该环境变量,则使用一个编译时定义的默认路径来初始化
  • 6.如果找到目标文件,则会调用package.loadfile来加载模块,否则就会去找C程序库
  • 7.搜索的文件路径是从全局变量 package.cpath获取,而这个变量则是通过环境变量LUA_CPATH`来初始
  • 8.搜索策略跟上面的一样,只不过现在换成搜索的是sodll类型的文件,如果找到那么require会通过package.loadlib来加载
相关推荐
玩电脑的辣条哥2 小时前
Python如何播放本地音乐并在web页面播放
开发语言·前端·python
ll7788115 小时前
LeetCode每日精进:20.有效的括号
c语言·开发语言·算法·leetcode·职场和发展
Jackson@ML6 小时前
Python数据可视化简介
开发语言·python·数据可视化
赵琳琅6 小时前
Java语言的云计算
开发语言·后端·golang
lly2024066 小时前
jQuery 杂项方法
开发语言
赵琳琅7 小时前
MDX语言的安全开发
开发语言·后端·golang
开开又心心的学嵌入式7 小时前
C语言——指针进阶应用
c语言·开发语言
开开又心心的学嵌入式7 小时前
C语言——指针基础知识
c语言·开发语言
lonelyhiker7 小时前
javascript的原型链
开发语言·javascript·原型模式
夏梓蕙8 小时前
Elixir语言的软件开发工具
开发语言·后端·golang