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. [转帖]OceanBase实验4:迁移MySQL数据到OceanBase集群

    服务器环境 1)12核48G,操作系统为centos 7.9系统,单节点三副本1-1-1集群. 2)源MySQL数据库:与OceanBase同一台服务器,版本为MySQL 5.7. 1.使用 mysq ...

  2. [转帖]MySQL联合索引(复合索引)

    Mysql联合唯一索引添加相同数据插入报错 联合索引在两个字段都存在唯一,将报错. 1.添加联合索引 alter table "表名" add unique index(`字段1` ...

  3. [转帖]手摸手搭建简单的jmeter+influxdb+grafana性能监控平台

    我安装的机器是阿里云的centos8机器,其他的系统暂未验证 1.安装influxdb influxdb 下载地址https://portal.influxdata.com/downloads/,也可 ...

  4. [转帖]Full GC (Ergonomics) 产生的原因

    发生Full GC,有很多种原因,不仅仅是只有Allocation Failure. 还有以下这么多: #include "precompiled.hpp" #include &q ...

  5. [转帖]linux块I/O总体概括

    直接先上重点,linux中IO栈的完全图如下: 系统中能够随机访问固定大小数据片的硬件设备称作块设备.固定大小的数据片称为块.常见的块设备就是硬盘了.不能随机访问的就是字符设备了,管理块设备比字符设备 ...

  6. [转帖]华为OpenEuler欧拉系统添加epel源方法

    https://blog.whsir.com/post-7002.html   由于国产华为OpenEuler欧拉系统的版本命名是22.03.22.03这种,并且在查看版本的路径中是/etc/open ...

  7. Nginx反向代理总结

    反向代理的种类 1. LVS的方案 2. DNS轮询的方案 3. Nginx的4层代理 4. Nginx的7层代理 5. 网络NAT的处理 Nginx的反向代理-四层` 编译时增加 --with-st ...

  8. Ubuntu2204设置固定IP地址

    前言 Ubuntu每次升级都会修改一部分组件. 从1804开始Ubuntu开始使用netplan的方式进行网络设置. 但是不同版本的配置一直在升级与变化. 今天掉进坑里折腾了好久. 所以这边总结一下, ...

  9. sshpass 免密码进行文件复制的方法

    1. 部分centos8 没有安装 sshpass 需要先安装 sshpass yum install sshpass 2. 需要增加一个配置文件, 避免因为 stickhost 检查 造成命令失效 ...

  10. 根据TxID获取上链数据

    根据TxID获取上链信息 前段时间应甲方爸爸的要求,需要在现有的业务系统中新增一个根据TxID来查询上链信息的接口.搜了一圈发现相关的信息很少,最后只能祭出终极大招:Read Source Code. ...