1 Lua 简介

​ Lua 是一个小巧的脚本语言,用标准C语言编写而成,由巴西里约热内卢天主教大学的 Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo 三人于 1993 年开发,设计目的是为了灵活嵌入应用程序,实现灵活的扩展和定制功能。

​ Lua 具有以下特性:

  • 脚本语言、解释型语言
  • 嵌入程序开发
  • 容易与其他语言相互调用
  • 轻量级
  • 面向过程编程
  • 函数式编程
  • 热更新

2 Lua 环境搭建

1)下载 bin 包

​ 点击 https://luabinaries.sourceforge.net/download.html,根据系统类型下载相应 bin 文件,如:Windows 系统下载[ lua-5.4.2_Win64_bin.zip](https://sourceforge.net/projects/luabinaries/files/5.4.2/Tools Executables/lua-5.4.2_Win64_bin.zip/download),如下:

2)解压并重命名文件

​ 将下载的 bin 文件解压,如笔者解压路径:D:\Program Files\Lua\bin,并将 lua54.exe 文件重命名为:lua.exe,如下:

3)配置环境变量

​ 右键此电脑,依次选择【属性→高级系统设置→环境变量→系统变量→Path】,将解压的 bin 目录添加到系统环境变量 Path 中。

4)验证环境

​ 在 cmd 命令行窗口输入:lua -v,如果打印了版本号,说明环境配置成功,如下:

3 Lua 输出、输入和注释

3.1 输出

1)在命令行中输入 Lua 代码

​ 在命令行中输入 lua,回车后进入 Lua 解释器环境,再输入 print("Hello World"),运行如下:

​ 按 Ctrl + C 即可退出 Lua 解释器环境。

2) 调用文件中 Lua 代码

​ 用记事本创建一个文件,重命名为 test.lua,编辑内容如下:

print("Hello World")

​ 使用命令行进入 test.lua 文件所在目录,输入:lua test.lua,打印如下:

3.2 输入

inputStr = io.read() --运行后会等待用户输入, 按回车键结束输入

3.3 注释

1)单行注释

--单行注释

2)多行注释

--[[
多行注释
]]

4 运算符

4.1 算术运算符

加(+)、减(-)、乘(*)、除(/)、幂(^)、取余(%)

4.2 比较运算符

小于(<)、大于(>)、小于等于(<=)、大于等于(>=)、等于(==)、不等于(~=)

4.3 逻辑运算符

与(and)、或(or)、非(not)
a and b --如果a为false, 则返回a, 否则返回b
a or b --如果a为true, 则返回a, 否则返回b
not a --如果a为true, 则返回 false, 否则返回false

​ 补充:Lua 中只有 false 和 nil 为假, 其他任何值都为真,0 也为真。

​ 案例:

print(1 and 2) --2
print(0 and nil) --nil
print(0 or 1) --0
print(not 0) --false
print(not nil) --true

5 Lua 变量

​ 变量的名称必须由字母、数字或下划线字符组成,且必须以字母或下划线开头。 大写++-和小写字母是不同的,因为 Lua 区分大小写。

5.1 数据类型

nil --空值,所有没有使用过的变量都是 nil,nil 既是值,又是数据类型
boolean --布尔型, 只有2个值, true和false
number --数值类型, 相当于C语言里的double
string --字符串
table --关系类型
function --函数类型

​ 获取数据类型:

--nil     number  string  boolean
print(type(nil), type(1), type("xxx"), type(true))

5.2 变量声明与赋值

1)全局变量与局部变量

--声明全局变量
a = 5
b = true
--声明局部变量
local name = "zhang san"
print(a, b, c, name) --5 true nil zhang san

​ 说明:nil 是 Lua 中的空值,所有没有使用过的变量都是 nil,nil 既是值,又是数据类型。

2)一组变量赋值

a, b, c = 1, true, "zhang san"
print(a, b, c) --1 true zhang san
d, e = 2
print(d, e) --2 nil
f, g = 3, 4, 5
print(f, g) --3 4

3)交换变量的值

a, b = 1, 2
a, b = b, a
print(a, b) --2 1

6 字符串

6.1 字符串定义

a = "xxx"
b = 'yyy'
c = [["zzz"]]
d = [['www']]
print(a, b, c, d) --xxx yyy "zzz" 'www'

6.2 字符串链接

print("xxx".."yyy") --xxxyyy
print("xxx"..123) --xxx123

6.3 字符串与其他类型转换

tonumber("123") --字符串转换为数字
tostring(123) --其他类型数据转换为字符串

6.4 字符串比较

print("abc" > "ab") --true
print("abc" < "ab") --false
print("zhang" > "wang") --true
print("zhang" < "wang") --false
print("xyz" == "xyz") --true
print("abc" == "xyz") --false

6.5 字符串函数

string.len(arg) --计算字符串长度
string.upper(str) --字符串全部转为大写字母
string.lower(str) --字符串全部转为小写字母
string.reverse(arg) --字符串反转
string.char(arg) --将整型数字转成字符并连接
string.byte(arg[,int]) --转换字符为整数值(可以指定某个字符,默认第一个字符)
--截取字符串, str: 待截取的字符串, i: 截取开始位置, j: 截取结束位置, 默认为-1, 表示最后一个位置
string.sub(str, i [, j])
--字符串替换, mainStr: 要操作的字符串, findStr: 要匹配的字符串, replaceStr: 替换的字符串, num: 替换次数(可以忽略,忽略后表示全部替换), return: 替换后的字符串和替换次数
string.gsub(mainStr, findStr, replaceStr, num)
--在str中查找subStr的, 如果找到了返回匹配的起点和终点索引, 否则返回nil
string.find (str, subStr, [init, [end]])
string.rep(string, n) --返回字符串string的n个拷贝
--字符串格式转换
string.format(...)

​ 应用:

str = "abcdefg"
print(string.len(str), str:len()) --7 7
print(string.sub(str, 2, 5), str:sub(2, 5)) --bcde bcde

7 表格 table

7.1 字典

1)字典初始化

tab = {
name = "zhang san",
age = 23,
single = true
}
--zhang san 23 true nil nil
print(tab["name"], tab["age"], tab.single, tab.xxx, tab[yyy])

2)字典赋值

tab = {}
tab[0] = 1
tab["name"] = "zhang san"
tab.single = true
--1 zhang san true
print(tab[0], tab["name"], tab.single)

7.2 列表

1)列表初始化

tab = {1, 2, 3}
--nil 1 2 3
print(tab[0], tab[1], tab[2], tab[3])

​ 说明:如果不设置下标,元素从 1 开始计数。

2)列表初始化(通过索引指定元素位置)

tab = {
1, 2, 3,
[0] = "Hello",
[10] = true
}
--Hello 1 2 3 true
print(tab[0], tab[1], tab[2], tab[3], tab[10])

7.3 table 常用函数

#tab --获取数组长度
--连接数组, 返回连接后的字符串, tab: 待连接的table, sep: 连接符(可省, 默认nil), start: 连接的起点位置(可省, 默认0), end: 连接的结束位置(可省, 默认最后一个元素位置)
table.concat(tab, sep, start, end)
--插入元素, tab: 待插入的table, pos: 待插入的位置(可省, 默认最后位置), value: 插入的元素
table.insert(tab, pos, value)
--删除元素, tab: 待删除的table, pos: 待删除的位置
table.remove(tab, pos)
--待排序的table, comp: 比较函数(可省, 默认升序)
table.sort(tab, comp)

​ 应用:

a = {"a", "b", "c", "d", "e"}
print(table.concat(a, ",")) --a,b,c,d,e
function sortFunc(a, b)
return b < a
end
table.sort(a, sortFunc)
print(table.concat(a, ":")) --e:d:c:b:a

8 流程控制语句

8.1 if 条件语句

1)if 语句

if conditions then
then-part
end

2)if - else 语句

if conditions then
then-part
else
else-part
end

3)if - elseif - else 语句

if conditions then
then-part
elseif conditions then
then-part
else
else-part
end

8.2 循环语句

1)for 循环语句

--start: 起点(包含), end: 终点(包含), step: 步长或增量(可省略)
for var = start, end, step do
loop-part
end

2)泛型 for 循环语句

--只打印列表元素
for i, v in ipairs(table) do
loop-part
end --打印所有元素
for k, v in pairs(table) do
loop-part
end

​ 案例 1:

tab = {10, true, "xxx"}
for i, v in ipairs(tab) do
print(i, v)
end
--[[打印如下:
1 10
2 true
3 xxx
]]

​ 案例 2:

tab = {10, true, "xxx"}
tab[0] = "yyy"
tab["zzz"] = 100
for i, v in ipairs(tab) do
print(i, v)
end
--[[打印如下:
1 10
2 true
3 xxx
]]

​ 案例 3:

tab = {10, true, "xxx"}
tab[0] = "yyy"
tab["zzz"] = 100
for k, v in pairs(tab) do
print(k, v)
end
--[[打印如下:
1 10
2 true
3 xxx
0 yyy
zzz 100
]]

3)while 循环语句

while condition do
loop-part
end

4)repeat 循环语句

--类似C语言的do-while语句
repeat
loop-part
until condition

5)break

​ 在循环过程中提前跳出循环,用法同C语言,如:

for i = 1, 10, 2 do
if i > 6 then
break
end
end

9 函数

9.1 函数定义与使用

1)函数定义

function function_name(args)
function-body
end

​ 说明:Lua 函数不支持重载,对于不同参数的同名函数,只有最后一个定义的同名函数生效。

2)函数使用

function show(str)
print(str)
end
--直接调用函数
show("xxx") --xxx
--可以省去括号
show "yyy" --yyy
--函数赋值后再调用, 类似C语言的函数指针
func = show
func("zzz") --zzz

​ 注意:函数调用应该放在函数声明后面,否则会报错。

9.2 函数返回值

​ Lua 支持多返回值,并且接收变量个数不一定要和函数返回参数个数一致。

function get()
return 1, 2, 3
end
--接收变量个数=返回参数个数
a, b, c = get()
print(a, b, c) --1 2 3
--接收变量个数<返回参数个数
a, b = get()
print(a, b) --1 2
--接收变量个数>返回参数个数
a, b, c, d = get()
print(a, b, c, d) --1 2 3 nil

9.3 匿名函数

func = function()
print("anonymous function")
end func()

9.4 常用 math 函数

--幂函数
sqrt、pow
--指数与对数函数
exp、log、log10
ldexp --如: math.ldexp(10, 3), 值为10*2^3=80
--三角函数
sin、cos、tan、acos、asin、atan
--取整函数
ceil、floor
--最值函数
min、max
--双曲线函数
cosh、sinh、tanh
--角度与弧度转换函数
deg、rad
--随机函数
random --如: math.random(1, 100), 获取1-100的随机数
randomseed --设置随机数种子, 如: math.randomseed(os.time())
--其他函数
abs
modf --把数分为整数和小数, 如: math.modf(10.12), 返回10 12
--常量
pi --3.1415926535898

​ 说明:使用 math 函数,都需要在前面加上 “math.”,如:math.abs(-1)。

10 模块

​ myMath.lua

function add(a, b)
return a + b
end function mul(a, b)
return a * b
end

​ test.lua

require("myMath")

print(add(1, 2)) --3
print(mul(2, 3)) --6

11 元表 metatable

​ 元表的作用主要是为了模拟面向对象特性,元表主要有 __index、__newindex、__call、__tostring 元方法。

11.1 设置元表

son = {}
parent = {}
newSon = setmetatable(son, parent)
print(newSon == son) --true
print(newSon == parent) --false

11.2 __index 元方法

1)__index 是个表格

​ 在读取子表的属性或函数时,若子表里不存在,就去元表的 __index 表里搜索,若元表也没有,就递归搜索元表的元表。

son = {
name = "son name",
func = function()
print("son func")
end
} parent = {
__index = {
name = "parent name",
age = 23,
func = function()
print("parent func")
end,
show = function()
print("show")
end
}
} setmetatable(son, parent)
print(son.name) --son name
print(son.age) --23
son.func() --son func
son.show() --show

2)__index 是个方法

​ 在读取子表的属性时,若子表里不存在,就调用元表的 __index 函数。

​ 案例一:

son = {}
parent = {
__index = function()
print("parent __index")
end
} setmetatable(son, parent)
print(son.age)
--[[打印:
parent __index
nil
]]

​ 案例二:

son = {}
parent = {
__index = function(tab, key)
print(tab, key)
end
} setmetatable(son, parent)
print(son.age)
--[[打印:
table: 0000000000179fd0 age
nil
]]

11.3 __newindex 元方法

1)__newindex 是个表格

​ 在修改子表的属性时,若子表里不存在,就在元表的 __newindex 表里添加该属性。

tempTab = {}
son = {}
parent = {
__newindex = tempTab
} setmetatable(son, parent)
son.name = "son name"
print(son.name) --nil
print(tempTab.name) --son name

2)__newindex 是个方法

​ 在修改子表的属性时,若子表里不存在,就调用元表的 __newindex 函数。

​ 案例一:

son = {}
parent = {
__newindex = function()
print("parent __newindex")
end
} setmetatable(son, parent)
son.name = "son name"
print(son.name)
--[[打印:
parent __newindex
nil
]]

​ 案例二:

son = {}
parent = {
__newindex = function(tab, key, value)
print(tab, key, value)
end
} setmetatable(son, parent)
son.name = "zhangsan"
print(son.name)
--[[打印:
table: 0000000000099cd0 name zhangsan
nil
]]

11.4 __call 元方法

​ 在以函数形式调用子表时(如:tab()),会调用元表的 __call 函数。

1)无参 call

son = {}
parent = {
__call = function()
print("parent __call")
end
} setmetatable(son, parent)
son() --parent __call

2)有参 call

son = {}
parent = {
__call = function(sonTab, arg)
print(sonTab, arg)
end
} setmetatable(son, parent)
son("xxx") --table: 0000000001019c90 xxx

​ 说明:第一个参数是调用的子表。

11.5 __tostring 元方法

​ 在获取子表输出内容时,会调用元表的 __tostring 函数。

son = {10, 20, name = "zhangsan"}
parent = {
__tostring = function(sonTab)
str = "{"
for k, v in pairs(sonTab) do
str = str..k..": "..v..", "
end
str = str.."}"
return str
end
} setmetatable(son, parent)
print(son) --{1: 10, 2: 20, name: zhangsan, }

12 面向对象编程

​ Lua 是面向过程编程语言,不支持面向对象编程,但可以使用元表模拟面向对象编程。本节将通过一个案例展示 lua 面向对象编程的写法。

​ student.lua

--使用lua模拟一个类

--1、创建表格, 添加字段
Student = {
name = "xxx",
age = 0,
sex = "0"
} --2、定义类的构造函数
--function Student.new(self, name, age, sex)
function Student:new(name, age, sex)
o = {}
setmetatable(o, self)
self.__index = self;
self.__tostring = function()
return "{name: "..self.name..", age: "..self.age..", sex: "..self.sex.."}"
end
self.name = name
self.age = age
self.sex = sex
return o
end --3、定义类的成员方法
--function Student.show(self)
function Student:show()
print(self.name, self.age, self.sex)
end --4、定义静态字段
Student.hair = "black" --5、定义静态方法
function Student.showHair()
print("hair=" .. Student.hair)
end

​ 说明:Student:new(name, age, sex) 等价于 Student.new(self, name, age, sex),Student:show() 等价于 Student.show(self)。

​ test.lua

require("student")
--创建Student实例
stu = Student:new("zhang san", 23, "male")
--调用Student的元表的tostring方法, 打印: {name: zhang san, age: 23, sex: male}
print(stu)
--访问stu实例的字段, 打印: zhang san 23 male
print(stu.name, stu.age, stu.sex)
--调用stu实例的方法, 打印: zhang san 23 male
--stu.show(stu)
stu:show()
--访问Student的静态字段, 打印: black
print(Student.hair)
--调用Student的静态方法, 打印: hair=black
Student.showHair()

​ 说明:stu:show() 等价于 stu.show(stu)。

​ 声明:本文转自【Lua】Lua基础语法

【Lua】Lua基础语法的更多相关文章

  1. Nginx详解二十二:Nginx深度学习篇之Lua解释器安装及基础语法

    解释器 Lua:Lua是一个简洁.轻量.可扩展的脚本语言 Nginx+Lua优势充分的结合Nginx的并发处理epoll优势的Lua的轻量实现简单的功能切高并发的场景 安装Lua 1.安装解释器:yu ...

  2. Lua基础语法讲解

    Lua 是什么? Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能. Lua 是巴西里约热内卢天主教大学( ...

  3. Lua基础语法学习笔记

    Lua是一门语言,我们可以使用一个库,可以在运行时去编译执行Lua中的代码,从而实现自己的内存中的数据和逻辑: 准备学习环境: 新建一个Lua项目目录,用来写我们的Lua代码: 进入目录,右键使用vs ...

  4. Lua - 基础语法

    Hello World 交互式编程 Lua 交互式编程模式可以通过命令 lua -i 或 lua 来启用: [huey@huey-K42JE lua]$ lua Lua 5.1.4 Copyright ...

  5. 【quick-cocos2d-x】Lua 语言基础

    版权声明:本文为博主原创文章,转载请注明出处. 使用quick-x开发游戏有两年时间了,quick-x是cocos2d-Lua的一个豪华升级版的框架,使用Lua编程.相比于C++,lua的开发确实快速 ...

  6. Cocos2d-x-Lua (2.x)脚本开发之 Lua语言基础

    从今天開始,往后将陆续更新Lua教程,主要是搭载Cocos2dx ,有不论什么疑惑或者不正确的地方.尽情指正.交流.探讨. 那么首先肯定是Lua语言基础的知识点.以下直接附上代码,凝视已经非常清楚.无 ...

  7. Lua学习二----------Lua的基本语法

    © 版权声明:本文为博主原创文章,转载请注明出处 Lua基本语法: 1.--表示单行注释 2.--[[--]]表示多行注释 3.Lua区分大小写 4.Lua中变量默认是全局变量,除非用local显式声 ...

  8. Lua Interface基础使用

    Lua是一种可爱的脚本语言,由Roberto Ierusalimschy.Waldemar Celes 和 Luiz Henrique de Figueiredo所组成并于1993年开发. 其设计目的 ...

  9. [译] Closures in Lua - Lua中的闭包

    原文:(PDF) . 摘要 一等(first-class)函数是一种非常强大的语言结构,并且是函数式语言的基础特性.少数过程式语言由于其基于栈的实现,也支持一等函数.本文讨论了Lua 5.x用于实现一 ...

  10. Python学习的个人笔记(基础语法)

    Python学习的个人笔记 题外话: 我是一个大二的计算机系的学生,这份python学习个人笔记是趁寒假这一周在慕课网,w3cschool,还有借鉴了一些博客,资料整理出来的,用于自己方便的时候查阅, ...

随机推荐

  1. C++静态库与动态库执行过程深入

    静态库与动态库 静态库 基本使用 静态库是将一组完整的功能,如一个提供了完整运算的计算器,进行封装为一个.a或.lib文件. 使用时仅需要在使用处include这个静态库的头文件.而后在编译时添加-L ...

  2. 面试官:小伙子来说一说Java中final关键字,以及它和finally、finalize()有什么区别?

    写在开头 面试官:"小伙子,用过final关键字吗?" 我:"必须用过呀" 面试官:"好,那来说一说你对这个关键字的理解吧,再说一说它与finally ...

  3. [转帖]AES算法(四)基本工作模式

    https://zhuanlan.zhihu.com/p/376077687 8 人赞同了该文章 本文所述工作模式可适用于 DES.AES 等分组密码算法中 分组密码算法只能加密固定长度为 N 比特的 ...

  4. [转帖]mysql 数据库视图迁移

    https://www.cnblogs.com/phpyangbo/p/6132821.html 最近做一个项目,为了方便查询,建了好多的视图表,正式上线的时候需要把本地数据库迁移到服务器上. 按照常 ...

  5. [转帖]PolarDB和Oceanbase的区别和联系

    PolarDB-X 和 OceanBase 都是阿里云提供的分布式关系型数据库产品,它们都具有高可用.高性能.分布式等特点.但是两者也存在一些差异. 数据库理论基础不同 PolarDB-X 基于传统的 ...

  6. [转帖]麒麟v10上部署TiDBv5.1.2生产环境的最佳实践

    https://tidb.net/book/tidb-monthly/2022/2022-07/usercase/tidb-v5-1-2 前言​ 笔者最近在一个银行项目中做 PoC 测试,由于客户选择 ...

  7. [转帖]探索惊群 ④ - nginx - accept_mutex

    https://wenfh2020.com/2021/10/10/nginx-thundering-herd-accept-mutex/   由主进程创建的 listen socket,要被 fork ...

  8. WorkStation的网络损耗

    WorkStation的网络损耗 背景 对周六遇到的问题进行了一下深入思考. 发现虽然可以通过WorkStation的方式来进行Clients以及新命令的扩容. 但是Workstation的桥接网络模 ...

  9. [转帖]Oracle 通过 Exadata 云基础设施 X9M 提供卓越的数据库性能和规模

    https://www.modb.pro/db/397202 32个节点的RAC 服务器 每个服务器 两个 64核心的AMD CPU 四个线程干管理 252个线程进行数据库处理 252*32=8064 ...

  10. SMFL 教程&个人笔记(2)

    本文大部分来自官方教程的Google翻译 但是加了一点点个人的理解和其他相关知识 转载请注明 原文链接 :https://www.cnblogs.com/Multya/p/16317401.html ...