【Lua】Lua基础语法

news2024/11/20 8:36:20

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,如下:

        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.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 字符串函数

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(...)

表格 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])

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
    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
    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

        说明:使用 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(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()
	print(self.name, self.age, self.sex)
end

--4、定义静态字段
Student.hair = "black"

--5、定义静态方法
function Student.showHair()
	print("hair=" .. Student.hair)
end

        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()
--访问Student的静态字段, 打印: black
print(Student.hair)
--调用Student的静态方法, 打印: hair=black
Student.showHair()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/110549.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基础IO——缓冲区

文章目录1. 缓冲区理解1.1 缓冲区在哪里1.2 刷新策略2. 标准输出和标准错误2.1 模拟perror1. 缓冲区理解 什么是缓冲区呢&#xff1f; 缓冲区的本质&#xff1a;就是一段内存 为什么要有缓冲区呢&#xff1f; 大家在日常生活中&#xff0c;如果我们想寄东西给朋友&#xff0c…

ELK集群部署---LogStash,Filebeat的部署

1. 环境规划: 主机名IP地址角色node1192.168.56.111 ElasticSearch(master) Zookeeper Kafka node2192.168.56.112 ElasticSearch(slave) Kibana Zookeeper Kafka node3192.168.56.113 ElasticSearch(slave) Zookeeper Kafka node4192.168.56.114 Logstash Filebeat 2. nod…

vue 实现类似甘特图大屏效果

最近在做大屏展示&#xff0c;其中一个需求是展示生产过程中投料情况&#xff0c;效果类似甘特图。 思路&#xff1a;1.先得到整个过程的开始时间startTime和结束时间endTime。计算出整个过长经历的时长。 2.计算横向坐标的开始时间start和结束时间end&#xff0c;坐标的开始时…

五分钟了解GRE是什么,四信GRE相关应用推荐

随着互联网新技术的发展以及智能化水平的提高&#xff0c;各企业对实时数据传输的需求也在不断提升&#xff0c;企业愈发重视数据中心的建设&#xff0c;各类虚拟网络技术相继被引入。今天&#xff0c;我们重点了解下云端“借道”鼻祖&#xff0c;善于“包装”的GRE&#xff0c…

新品上市|四信LTE Cat.1无线数传终端 推进中低速蜂窝典型应用

当前&#xff0c;物联网作为新型信息基础设施&#xff0c;已成为推动制造业、零售业、金融业、服务业等行业数字转型、智能升级、融合创新的重要支撑。《“十四五”信息通信行业发展规划》提出&#xff0c;要推进移动物联网全面发展&#xff0c;推动存量2G/3G物联网业务向NB-Io…

SSM医院病历

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a;

CentOS7安装git

CentOS7安装git前言一、git介绍二、使用yum安装git1.安装git2.查看git版本3.移除git三、源码包安装git1.安装依赖2.下载源码包3.解压4.git安装5.查看git版本总结前言 CentOS7安装git&#xff0c;刚开始使用yum安装git&#xff0c;发现安装的版本默认是1.8.3.1&#xff0c;如果…

yaml 资源配置清单使用详解——k8s声明式资源管理

目录 一、kubectl 操作 yaml 文件 1.应用yaml文件指定的资源 2.删除yaml文件指定的资源 3.查看资源的yaml格式信息 4.查看yaml文件字段说明 5.修改yaml文件指定的资源 &#xff08;1&#xff09;离线修改 &#xff08;2&#xff09;在线修改 二、编辑yaml配置清单生成…

Java开发如何通过IoT边缘ModuleSDK进行进程应用的开发?

摘要&#xff1a;为解决用户自定义处理设备数据以及自定义协议设备快速接入IOT平台的诉求&#xff0c;华为IoT边缘提供ModuleSDK&#xff0c;用户可通过集成SDK让设备以及设备数据快速上云。本文分享自华为云社区《【华为云IoTEdge开发实战】Java开发如何通过IoT边缘ModuleSDK进…

字符串函数剖析(2)

最慢的步伐不是跬步&#xff0c;而是徘徊&#xff1b;最快的脚步不是冲刺&#xff0c;而是坚持。——《人民日报》 字符串函数的重点&#xff1a; 文章不长&#xff0c;是为了让你一点点消化所有内容&#xff1a; 1.strncpy函数的脾气 1.1模拟实现strncpy函数 2.strncmp函数…

马化腾说视频号是全公司希望

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 这应该是&#xff0c;腾讯这家公司创办以来&#xff0c;马化腾最焦虑也最外露的一次讲话了&#xff0c;对于腾讯内部的大会&#xff0c;马化腾先生作了重要发言&#xff0c;因其在内部员工大会的讲…

边界网关协议BGP(计算机网络-网络层)

目录 因特网分层路由 分层路由和自治系统 边界网关协议 BGP BGP 的设计目标 BGP 发言人 路径向量算法 BGP 协议的要点 因特网分层路由 规模问题 路由选择算法将很难收敛 交换的路由信息会占用大量的带宽 管理问题 许多单位不愿意外界了解自己单位网络的具体细节 希望采用…

新能源汽车补贴即将取消,汽车金融的促进作用逐渐显现

中国新能源汽车产业发展强劲。自2015年起&#xff0c;新能源汽车销量连续7年位居世界第一。特别是2021年以来&#xff0c;在政策支持、技术驱动、消费者接受度提升等多重因素共同影响下&#xff0c;中国新能源汽车市场实现了超越式的发展。2022年1-10月&#xff0c;新能源汽车批…

这份京东T8级程序员整理的新版Spring Cloud手抄本,把微服务讲透了

近几年&#xff0c;微服务可谓是红的发紫&#xff0c;仿佛一时间所有系统无不以拆分为荣&#xff0c;以构建烟囱型应用为耻。最近&#xff0c;一位朋友刚好赶上公司基础服务的微服务化项目&#xff0c;加上之前又主动学习了不少微服务的内容&#xff0c;便主动请缨参与到项目里…

前端实现网站悼念【灰色效果】几行代码轻松解决

博主介绍 &#x1f4e2;点击下列内容可跳转对应的界面&#xff0c;查看更多精彩内容&#xff01; &#x1f34e;主页&#xff1a;水香木鱼 &#x1f34d;专栏&#xff1a;CSS3 文章目录 简介&#xff1a;这是一篇有关【前端实现网站悼念【灰色效果】几行代码轻松搞定】的文章&…

遗传编程(Genetic Programming, GP)

1. 绪言 1.1 遗传编程概述 \quad\quad自计算机出现以来&#xff0c;计算机科学的一个重要目标是让计算机自动进行程序设计&#xff0c;即只要明确地告诉计算机要解决的问题&#xff0c;而不需要告诉它如何去做&#xff0c;遗传规划便是在该领域内的一种尝试。它采用遗传算法的…

IDEA反编译Jar包

一.安装Java Bytecode Decomplier插件 (1) File–>Settings–>Plugins &#xff0c;搜索 Java Bytecode Decomplier 插件 (2) 查看安装插件的路径 File->Import Setting 注意&#xff1a;如果你的插件里面搜不到 Java Bytecode Decomplier&#xff0c;但是能搜到…

spring之Bean的生命周期

文章目录一、Bean的生命周期之五步1、准备User类2、spring配置文件3、测试类4、运行结果二、Bean的生命周期之七步1、实现BeanPostProcessor类2、配置文件3、运行结果&#xff1a;三、Bean的生命周期之十步1、点位12、点位23、点位3四、Bean的作用域一、Bean的生命周期之五步 …

Coinbase或在不久使用Zebec发放工资,并对Web3支付赛道发展寄予厚望

流支付协议Zebec Protocol目前已经完成了生态向BNB Chian上的迁移&#xff0c;目前得到了以PancakeSwap为代表的头部生态的支持。在12月20日Zebec生态在PancakeSwap官方的支持下&#xff0c;经过社区投票&#xff0c;ZBC通证上线了糖浆池&#xff0c;并有望继续上线Binance。而…

ELK集群部署---Kibana的部署

1. 环境规划&#xff1a; 主机名IP地址角色node1192.168.56.111 ElasticSearch(master) Zookeeper Kafka node2192.168.56.112 ElasticSearch(slave) Kibana Zookeeper Kafka node3192.168.56.113 ElasticSearch(slave) Zookeeper Kafka node4192.168.56.114 Logstash Filebe…