目录

  • 基本用法
  • 介绍
  • 开发环境搭建
  • 执行程序
  • local局部变量
  • Lua基本数据类型
  • 字符对象
  • 函数对象
  • 顺序执行
  • 基本表达式
  • 条件语句
  • 循环语句
  • Lua字符串接口
  • 遍历表
  • 表的接口
  • 多返回值
  • unpack函数
  • require
  • module
  • self机制
  • 元表


基本用法

介绍

1: 高效的,轻量级的,嵌入式脚本语言;
2: Lua是一个语言标准;
3: 脚本语言有对应的解释器(虚拟机),解释器有两个分支: 官方lua, LuaJIT(高效,即时编译技术);

开发环境搭建

1: 下载LuaDist;
2: 加压后放到对应的目录下;
3: 将bin目录加入到电脑的环境Path;
4: lua解释器, luac 字节码编译器: lua代码–> lua字节码;

执行程序

1: 编写main.lua;
2: 编写代码print(“HelloWorld!!!”);
3: lua main.lua使用lua解释器解释执行lua代码;
4: luac 可以将lua文件编译成lua字节码;
5: lua执行字节码;

lua .\main.lua #命令行执行

local局部变量

1: 定义一个局部变量: local 变量名称
2: 局部变量定义在哪里,那么它的作用范围就在哪里;
3: 系统会为局部变量分配一个内存,这个内存只能存基本数据类型或复杂数据类型的引用;
4: 变量在运行的时候存的是什么就是什么;
5: print(变量名称),打印一个变量
6: 如果变量没有赋值或一个空的值,我们可以用nil来表示;
7: 如果是一个不存在的变量或名字,也是nil;

Lua基本数据类型

1: Lua基本的数据类型: 整数, 小数, 逻辑数;
2: Lua不分整数和小数;
3: true, false
4: 注释单行: --,

1: 定义一个表 {key= value, key2 = value, [整数] = value, …}
2: key可以是整数,字符串
3: value可以是任意类型;
4: 访问value的每个元素 表[key], 表.key
5: Lua没有数组, 只有表;

字符对象

1: 字符串对象: 一串文字;
2: 它也是一种复杂的数据对象;

函数对象

1: function name(参数1, 参数2…)
end
2: 变量可以保存函数对象;
3:return [返回值]: 返回语句,可以带返回值
4: 函数调用,跳入函数对象,一条一条语句,遇到return后回到函数开始调用的下一条语句

Demo

print("hello")
print()

local temp = "hello world"
print(temp)

local obj = nil
local m
print(m)
print(obj)

local list = {
	[0] = 1,
	helloworld = 3,
}

print(list)
print(list[0])   --整数索引
print(list["helloworld"])
print(list.helloworld)
list.test = "test2"
print(list.test)
print(list["test"])

--函数
function add_func(a, b)
	print(a, b)
	return a + b

end

add_func(4, 4)

local func_ptr = add_func

func_ptr(4, 5)

local tmp = add_func(4, 5)

print(tmp)

顺序执行

Lua跟C不同的地方在于,运行是不从main函数开始的,直接从.lua的第一句开始执行

基本表达式

local temp
temp = 3

-- +-*/运算

temp = temp + 2
print(temp)  --5

-- 括号改变优先级
temp  = 1 + 2 * 3
print(temp)  --7
temp  = (1 + 2) * 3 
print(temp)  --9

--字符串的加法 ..
temp = "hello" .. "world"
temp = temp .. "!"
print(temp)  --helloworld!

--lua没有简化表达式
temp = 1
-- temp += 3  报错  -= *= /= ++ -- 等都会报错

条件语句

--如果为真执行if, 如果为假就不会执行
--执行if语句的时候,首先会判断条件是否为真
-- >, >=, <=, ~=(c语言中的!=), == 判断
temp = 3
if true then
	print("do if")
end

if temp >=3 then
	print("TRUE")
end

if temp ~= 4 then
	print("TRUE")
end

--多个条件的判断 and与 or或
if true and true then
	print("TRUE")
end

--and 两个条件都成立才为真
print(true and true)
print(true and false)
--or 只要有一个条件成立,为真
print(true or false)
print(false or false)

-- if else  如果if的条件成立, 就执行if, 否则执行else
temp = 1
if temp > 2 then
	print("true")
else
	print("else")
end

-- elseif(中间没空格,跟c语言区别)

temp = 1
if temp > 2 then
	print("true")
elseif temp == 1 then
	print("temp == 1")
else
	print("else")
end

循环语句

1: for循环语句

for exp1(开始), exp2(结束), exp3(步长) do
      
 end

步长可以省略,默认为1;bi’ch
2: while循环语句

while 条件 then 
end

Demo

--循环语句
--打印1~10
local i = 1
for i = 1, 10 do --可以不写步长,默认为1
	print(i)
end

for i = 1, 10, 2 do
	print(i)
end

for i = 10, 1, -1 do
	print(i)
end

local sum = 0
for i = 1, 100, 1 do
	sum = sum + i
end
print(sum)  --5050


--while
i = 1
sum = 0
while i <= 100 do  --只要条件为真就会执行while
	sum = sum + i
	i = i + 1
end
print(sum)

Lua字符串接口

--字符串和字符串的相加
local l1 = "hello"
local l2 = "world"

print(l1 .. l2)

--字符串和基本的数据相加
print(l1 .. 8);
--end

--数字转字符串
print(tostring(8.4))
print("" .. 8.4)
local value = 7
print("" .. value)
--end

--字符串转数字
print(tonumber("9.6"))
--end

--常用字符串接口
--求字符串的字节数
local l3 = "hello world"
print(string.len(l3))

--返回重复n次的字符串s的串 string.rep(s, n)
local l4 = "hello hello hello abc abc "
print(string.rep("hello",3))
print(string.rep("abc",2))

--将大写转为小写
local l5 = "AAbbCCdd"
l6 = string.lower(l5)
print(l6)
--将小写转为大写
local l7 = "AAbbCCdd"
l8 = string.upper(l7)
print(l8)
--end

-- string.sub(s,i,j): 从第i个到第j个之间的字符串,索引从1开始不是从0开始;
local l9 = "hello world"
print(string.sub(l9, 2, 5))
--end

--string.format(); 和C语言printf一样,格式化输出数据;
--//2022.7.25
local date_ = string.format("%d-%d-%d", 2022, 7, 25);
print(date_)
--end

--string.find: 子串查找函数;
local l10 = "hello world"
local index = string.find(l10, "world") --索引从1开始不是从0开始
print("world at pos: " .. index)
--end

--string.gsub: 字符串替换函数, string.gsub("hello", "l", "n", 1); 替换的个数
local l11 = "hello world"
local l12 = string.gsub(l11, "ll", "ww")
print(l12) --hewwo world

l11 = "llllllllll"
l12 = string.gsub(l11, "ll", "ww", 2) --指定替换个数
print(l12) --wwwwllllll
--end

补充
格式化转义码:

%c - 接受一个数字, 并将其转化为ASCII码表中对应的字符
%d, %i - 接受一个数字并将其转化为有符号的整数格式
%o - 接受一个数字并将其转化为八进制数格式
%u - 接受一个数字并将其转化为无符号整数格式
%x - 接受一个数字并将其转化为十六进制数格式, 使用小写字母
%X - 接受一个数字并将其转化为十六进制数格式, 使用大写字母
%e - 接受一个数字并将其转化为科学记数法格式, 使用小写字母e
%E - 接受一个数字并将其转化为科学记数法格式, 使用大写字母E
%f - 接受一个数字并将其转化为浮点数格式
%g(%G) - 接受一个数字并将其转化为%e(%E, 对应%G)及%f中较短的一种格式
%q - 接受一个字符串并将其转化为可安全被Lua编译器读入的格式
%s - 接受一个字符串并按照给定的参数格式化该字符串

遍历表

--数组部分, --> 索引从1开始
local list_table = {1, 2, 3, 4, 5}
--数组部分的访问是从索引(1)开始
print(list_table[1], list_table[2], list_table[3])

--#返回数组部分的长度,必须要求是连续的,比如,在11位置加一个
list_table[11] = 11
print(#list_table) --打印结果还是5


--非数组部分
list_table.test_key = "test_value"
print(list_table["test_key"])
print(list_table[11])
--end

--遍历lua里面的数组部分的数据
local index = 1
for index = 1, #list_table do
	print(list_table[index])
end
print("--------------------")

--ipairs遍历lua表里的数组部分
local k, v
for k, v in ipairs(list_table) do
	print(k, v)
end
print("--------------------")

--pairs遍历lua表里的所有数据
for k, v in pairs(list_table) do
	print(k, v)
end
print("--------------------")

表的接口

--table.insert(table, pos, value): 
     --在table的数组部分指定位置(pos)插入值为value的一个元素, 
	 --pos参数可选, 默认为数组部分末尾
table.insert(list_table, 8)

for k, v in pairs(list_table) do
	print(k, v)
end
print("--------------------")

table.insert(list_table, 2, 8)
for k, v in pairs(list_table) do
	print(k, v)
end
print("--------------------")

--table.remove(table, pos)
--函数删除并返回table数组部分位于pos位置的元素. 
---其后的元素会被前移. pos参数可选, 默认为table长度, 即从最后一个元素删起
table.remove(list_table, 2)
for k, v in pairs(list_table) do
	print(k, v)
end
print("--------------------")

--返回这个表里有多少元素,数组部分,作用跟#类似
print(table.getn(list_table))
print("--------------------")
--end

--排序表
local array_data = {3, 2, 6, 5, 9, 8}
for k, v in ipairs(array_data) do
	print(k, v)
end
print("--------------------")
print("排序后(从小到大)")

table.sort(array_data)
for k, v in ipairs(array_data) do
	print(k, v)
end
print("--------------------")

--如果从大到小,需要自定义比较函数来进行排序
local function comp1(lhs, rhs)
	if lhs < rhs then 
		return false
	else
		return true 
	end
end
print("排序后(从大到小)")
table.sort(array_data, comp1)
for k, v in ipairs(array_data) do
	print(k, v)
end
print("--------------------")

多返回值

-- 多返回值
function mul_return_func()
    return 3, "Hello World"
end

local first, secode = mul_return_func()
print(first, secode)

first = mul_return_func()
print(first)

unpack函数

-- unpack函数, 解开表里的单个的值
local array_data = {1, 2, 3, 4, 5, 6}
local _, _, _, lhs, rhs = unpack(array_data)
print(lhs, rhs) -- 4, 5

require

用于加载其他lua脚本
代码模块化后,会分成多个lua文件, 用require加载代码,不需要后缀名(.lua)

-- require("main")
local ret = require("math_func")
--print(ret)
-- 多次require只会装载和执行一次lua脚本, 但是第二次require时
-- 会发现前面已装载过, 所以直接返回第一次装载的返回值.

-- 直接调用装载函数
local add_data = add_func_1(1, 2)
print(add_data)


local i = ret.add(2, 3)
print(i)

math_func.lua

function add_func_1(a, b)
    print(a, b)
    return a + b
end

print("math.lua...........")

-- 加上local以后就是内部函数,在外边调用找不到
local function test_func(...)
    -- body
end

-- 方便用户使用和管理,模块的接口函数给统一导出
-- 做了一个表,吧接口函数设置到表中,并return回去
local list = {
    add = add_func_1
}
return list

module

设置成全局

-- 调用module, 让他作成全局可以找到的模块
module("device", package.seeall)

function get_device_name()
    return "guest1234"
end
require("device")  --只require一次就好

local ret = device.get_device_name()
print(ret)

其他.lua

local ret = device.get_device_name()
print(ret)

self机制

-- self 机制
-- .和:的区别
-- 用: 定义的函数,多一个机制self,类似C++中的this指针
local a = {}

function a.test()
    print("a.test")
end
a.test()

local b = {}
function b:test()
    -- self, 调用这个函数的表的实例
    print("b:test", self)
end
b:test() -- test函数里面self就是b

元表

local a = {}

local meta_a = {
    __index = {
        name = "xiaoming",
        age = 18,
        sex = 0
    }
}

-- 两个表相加,第一个参数和第二个参数都是表
-- meta_a叫做a的元表;
setmetatable(a, meta_a) -- 设置表的元表;
print(getmetatable(a)) -- 获取表的元表;

-- 元表里面有个很重要的key: __index
-- 特点:
-- 当搜索一个表的key的时候,若果在当前的表里面没有搜索的到,
-- lua解释器, 会去我们这个表的元表里面的__index这个key中查找
-- 优先在自己这个表里面去查找
print(a.name)