掌握 lua 最基本的语法

这篇博客介绍了Lua语言的基础知识,包括应用场景、环境安装(Linux和Windows)、两种编程模式(交互式和脚本式)、注释、变量、循环、if语句、函数、模块与包的使用。此外,还详细讲解了Lua中的面向对象编程,以及如何通过OpenResty访问MySQL和Redis数据库。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Lua 是一种轻量小巧的脚本语言

应用场景

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

环境安装
  • linux:下载源码包并在终端解压编译即可
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
  • window:https://github.com/rjpcomputing/luaforwindows/releases
两种编程模式
  • 交互式编程:Lua 交互式编程模式可以通过命令 lua -i 或 lua 来启用:
$ lua -i 
$ Lua 5.3.0  Copyright (C) 1994-2015 Lua.org, PUC-Rio
> print("Hello World!")
Hello World!
> 
  • 脚本式编程:将程序写在文件中,该文件以 lua 为后缀名。
//在hello.lua文件中编写程序
print("Hello World!")

//执行hello.lua
lua hello.lua
Hello World!
注释
  • 单行注释:--
  • 多行注释
--[[
 多行注释
 多行注释
 --]]
变量
  • 全局变量:在默认情况下,变量总是认为是全局的。全局变量不需要声明,给一个变量赋值后即创建了这个全局变量,访问一个没有初始化的全局变量也不会出错,只不过得到的结果是:nil。如果你想删除一个全局变量,只需要将变量赋值为nil。
  • 数据类型
nil	这个最简单,只有值nil属于该类,表示一个无效值(在条件表达式中相当于false)。
boolean	包含两个值:false和true。
number	表示双精度类型的实浮点数
string	字符串由一对双引号或单引号来表示
function	由 C 或 Lua 编写的函数
userdata	表示任意存储在变量中的C数据结构
thread	表示执行的独立线路,用于执行协同程序
table	Lua 中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字、字符串或表类型。在 Lua 里,table 的创建是通过"构造表达式"来完成,最简单构造表达式是{},用来创建一个空表。

注意:
1、type函数得到变量的数据类型
print(type("Hello world"))      --> string

2、在对一个数字字符串上进行算术操作时,Lua 会尝试将这个数字字符串转成一个数字:
> print("1" + 2)
3.0
> print("2" + 1)
3.0

3、字符串连接不使用 ‘ + ’,需使用 ‘ .. ’
print("wo" .. 'hu')
wohu

4、local b = 5         -- 前面+local成为局部,无论时是变量还是函数都可以加上local成局部变量和私有函数

55.1、创建table:
tb = {} tb[2]="a"
or  
tb = {1 , "23"} -->tb[1]=1,tb[2]="23"
or 
tb = {foo = 3}-->tb[foo]=3
5.2、table中的索引可以时数值or字符串:
a = {}
a["key"] = "value"
key = 10
a[key] = 22
5.3、不同于其他语言的数组把 0 作为数组的初始索引,在 Lua 里表的默认初始索引一般以 1 开始。
5.4、table 不会固定长度大小,有新数据添加时 table 长度会自动增长,没初始的 table 都是 nil。

6、lua有许多方法可以对字符串进行操作,
如:string.upper("abc")将abc转换为大写,string.reverse(arg)翻转字符串
循环
当while判断为true时,执行循环体
while( true )
do
   print("循环将永远执行下去")
end

exp1:初始值,exp2:目标值,exp3:步长
for var=exp1,exp2,exp3 do  
    <执行体>  
end  

//lua迭代器案例
a = {}
a["k1"] = "v1";
a[3] = 3;
for k, v in pairs(a) do
    print(k .. " : " .. v)  //k1:v1  3:3
end

先执行一次循环体,当condition为true时,退出循环
repeat
   statements
until( condition )

注意:可以嵌套
如:
while( condition)
do
   for var=exp1,exp2,exp3 do  
    <执行体>  
	end  
end
if语句
if(布尔表达式)
then
   --[ 布尔表达式为 true 时执行该语句块 --]
else
   --[ 布尔表达式为 false 时执行该语句块 --]
end
函数
function max(num1, num2)
   if (num1 > num2) then
      result = num1;
   else
      result = num2;
   end
   return result;
end
模块与包

解决:如何在一个lua文件中使用另一个lua文件中的变量和函数?
1、编写一个模块。

-- 文件名为 module.lua
-- 定义一个名为 module 的模块
module = {}
 
-- 定义一个常量
module.constant = "这是一个常量"
 
-- 定义一个函数
function module.func1()
    io.write("这是一个公有函数!\n")
end
 
local function func2()
    print("这是一个私有函数!")
end
 
function module.func3()
    func2()
end
 
return module

2、在其他lua文件中引用该模块。

//require("模块名")
require("module")

//调用模块中的变量和函数
print(module.constant)
module.func3()

注意:对于自定义的模块,模块文件不是放在哪个文件目录都行,函数 require 有它自己的文件路径加载策略,它会尝试从 Lua 文件或 C 程序库中加载模块。
编辑环境变量:export LUA_PATH="~/lua/?.lua;;"
使之生效:source ~/.profile
我们自定义的模块可以放置在该目录下,使用命令:cd ~ 可以进入该目录

面向对象

lua 中的 function 可以用来表示方法。那么LUA中的类可以通过 table + function 模拟出来。
我们需要先知道Lua 元表(Metatable)
在 Lua table 中我们可以访问对应的 key 来得到 value 值,但是却无法对两个 table 进行操作(比如相加)。
使用元表我们可以定义 Lua 如何计算两个 table 的相加操作 a+b。

  • setmetatable(table,metatable): 对指定 table 设置元表(metatable)
  • getmetatable(table): 返回对象的元表(metatable)。
  • 设置元表:mytable = setmetatable({m1},{m2})把 m2 设为 m1 的元表
  • __index 元方法:这是 metatable 最常用的键。当你通过键来访问 table 的时候,如果这个键没有值,那么Lua就会寻找该table的metatable(假定有metatable)中的__index 键。如果__index包含一个表格,Lua会在表格中查找相应的键。
-- 元类
Rectangle = {area = 0, length = 0, breadth = 0}

-- 派生类的方法 new
function Rectangle:new (o,length,breadth)
  o = o or {}
  setmetatable(o, self)
  self.__index = self
  self.length = length or 0
  self.breadth = breadth or 0
  self.area = length*breadth;
  return o
end

-- 派生类的方法 printArea
function Rectangle:printArea ()
  print("矩形面积为 ",self.area)
end
  • 创建对象
r = Rectangle:new(nil,10,20)
  • 访问对象属性、方法
print(r.length)
r:printArea()
  • 继承:使用上面的类
--首先创建对象,但调用方法时,不传入参数
Ex = Rectangle:new()
-- 继承类方法 new
function Ex:new (o,length,breadth)
  o = o or Shape:new(o,length,breadth)
  setmetatable(o, self)
  self.__index = self
  return o
end
--继承类的新的方法
function Ex:printArea ()
  print("ex: ",self.area)
end
数据库访问
  • 借助nginx+OpenResty访问mysql
luasql = require("resty.mysql")

--创建实例  
--获取uri上的id
local param = ngx.req.get_uri_args()["id"]
local db, err = mysql:new()  
--设置超时时间(毫秒)  
db:set_timeout(1000)
--连接数据库
local props = {  
	host = "127.0.0.1",  
	port = 3306,
	database = "db1", 
	user = "root",
	password = "aabsabs"  
} 
local ok, err = db:connect(props)

local select_sql = " select * from test where id = "..param

--执行数据库操作
res,err = db:query(select_sql)
for i,row in ipairs(res) do
	for name,id in pairs(row) do
		ngx.say(name,":",id)
	end
end
  • 借助nginx+OpenResty访问redis
local redis = require "resty.redis"
local red = redis:new()
red:set_timeout(1000) 
red:connect("127.0.0.1", 6379)
local res, err = red:get("key")
ngx.say("{ans:",res,"}")
return
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值