大数据最新lua学习笔记_lua goto(1),面试必备

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

	- [1.2 lua语言应用场景](#12_lua_16)

1、lua语言介绍

1. 1 语言介绍
  • Lua 是一个小巧的脚本语言。 其设计目的是为了通过灵活嵌入应用程序中从而为应用程序提供灵活的扩展和定制功能。
  • Lua由标准C编写而成,几乎在所有操作系统和平台上都可以编译,运行。
  • Lua并没有提供强大的库,这是由它的定位决定的。
  • 所以Lua不适合作为开发独立应用程序的语言。Lua 有一个同时进行的JIT项目,提供在特定平台上的即时编译功能。
  • Lua由标准C编写而成,代码简洁优美,几乎在所有操作系统和平台上都可以编译,运行。
  • 一个完整的Lua解释器不过200k,在所有脚本引擎中,Lua的速度是最快的。
  • 这一切都决定了Lua是作为嵌入式脚本的最佳选择。

速度快、跨平台、开源、即时编译。

1.2 lua语言应用场景
  • 游戏开发-用来做热更。
  • 独立软件应用脚本。 Photoshop
  • Web开发 应用脚本。
  • WEB服务器中间件。 nginx支持扩展,lua写个扩展

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ChmuNnvi-1665330518827)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20220925011711411.png)]

  • 扩展和数据库操作脚本插件如:MySQL Proxy 和 MySQL WorkBench
  • 缓存操作脚本。 秒杀系统,用lua把一个非原子操作变成原子操作、锁。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ti87pIWg-1665330518830)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20220925011617505.png)]

  • 安全系统,如入侵检测系统。

官网:https://www.lua.org/

百度百科:https://baike.baidu.com/item/lua

2、开发环境配置与hello world

2.1 开发环境配置
  • 下载源代码包。
  • 编译。
  • 测试版本:lua -v。

windows下载网址:https://www.lua.org/download.html

Lua是用纯ANSI实现的,可以在所有有ANSI C编译器的平台上不加修改地编译。Lua也可以像C++一样干净地编译。

Lua非常容易构建和安装。有详细说明但是这里有一个简单的终端会话,它下载当前版本的Lua并在Linux中编译它:

Linux下载编译指令:

curl -R -O http://www.lua.org/ftp/lua-5.4.4.tar.gz
tar zxf lua-5.4.4.tar.gz
cd lua-5.4.4
make all test

运行上面四条指令之后出现:lua与luac表明编译成功。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-38PyICIJ-1665330518831)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20220925020632089.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zzwRXbuc-1665330518831)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20220925020656065.png)]

lua是运行lua文件,luac与编译lua文件。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jNmGolqG-1665330518832)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20220925020740254.png)]

  • luac -o outfilename sourcefilename.lua 是给sourcefilename.lua起个名字叫 outfilename。
  • g++/gcc -o outfilename sourcefilename.cpp。
  • 两者非常类似。
2.2 输出hello world

只需要用打印函数print就可以:

Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> print (hello world)
stdin:1: ')' expected near 'world'
> print hello world
stdin:1: '=' expected near 'hello'
> print ('hello world')
hello world
> print ('hello world')


3、变量命名规范

--[[

变量命名规范:

 lua弱语言类型(动态语言类型),定义变量的时候,不需要类型修饰。

 而且,变量随时都可以改变。


 每行代码结束的时候,要不要分号都可以。


 变量名由数字、字母、下划线组成,不能由数字开头,也不能是保留字(关键字),而且也不可以是特殊字符。

 变量名区分大小写,避免创建下划线开头加大写字母组成的变量名。因为可能会有命名冲突 --VERSION 这就是lua里面的关键字。

变量类型

 变量分为三种类型,全局变量、局部变量、表字段

 默认创建的都是全局变量,局部变量用local修饰


代码块(作用域)

 do
 ....

 end

]] --

代码示例:

a=123     --int
print(a)

a="abc"  --string
print(a)

a=true   --bool
print(a)

a123=123
print(a123)
a_123=123
print(a_123)
_a=123
print(_a)
_123_a=123 
print(_123_a)
--这里由数字开头 123\_a=123 --非法的

A123=456
print(A123)
abc=123
print(abc)
ABC=123
print(123)

local xyz=123 --局部变量
print(xyz)

--[[
{
 int a=123; 这里是C/C++语言中的作用域
}
]] --
abcd=123
--代码块
do
    xyz=123
    local XYZ=123
    print(abcd)
    print(xyz)
    print(XYZ)
end

print("\n")
print(abcd)
print(xyz)
print(XYZ)

输出结果:

PS D:\lua代码>  & 'c:/Users/hp/.vscode/extensions/actboy168.lua-debug-1.59.0-win32-x64/runtime/win32-x64/lua54/lua.exe' '-e' 'dofile[[c:/Users/hp/.vscode/extensions/actboy168.lua-debug-1.59.0-win32-x64/script/launch.lua]];DBG[[16296,ansi]]' 'D:\lua代码/变量命名规范/变量命名规范.lua'
123
abc 
true
123
123
123
123
456
123
123
123
123
123
123


123
123
nil
PS D:\lua代码> 

4、基本数据类型一

--[[

基本数据类型
 Lua 中有八种基本类型: nil、boolean、number、 string、function、userdata、 thread和table

 number 包括整型和浮点型

 string 单引号,双引号都表示string,不管是单引号,双引号,单个字符多个字符

 转义 用反斜杠 \n 换行符 \t 制表符
 原始输出用 [[ \] \]

 userdata 自定义数据格式
 thread 协程
 table 表

 在lua 中,只有false 和 nil 才表示假
 0和空串表示真


 库函数type返回一个描述给定值类型的字符串
 type (v)返回其唯一参数的类型,编码为字符串

]]--

a=nil
print(type(nil))

print(type(true))
print(type(boolean))

print(type(123))
print(type(111))
print(type(000))
print(type(1.123123))

--不管是单引号,双引号,单个字符多个字符
a='abc'
b='a'
c="abc"
d="a"
print(type(a))
print(type(b))
print(type(c))
print(type(d))

a='a\nb\ncd\tfd'
print(a)
b=[['a\nb\ncd\tfd']]
print(b)

print(type(type))
print(type(print))
print(type({}))

a1=nil

if a1 then
    print("真")
else
    print("假")
end

b1=0

if b1 then
    print("真")
else
    print("假")
end

c1=""

if c1 then
    print("真")
else
    print("假")
end



输出结果:

nil
boolean
nil
number
number
number
number
string
string
string
string
a
b
cd      fd
'a\nb\ncd\tfd'
function
function
table
假
真
真
PS D:\lua代码> 

5、基本数据类型二:function

--[[

 基本数据类型
 Lua有8种数据类型:nil,boolean,number,string,function,userdata,thread和table

 function 在lua中一个基本的数据类型是第一类值

 格式
 function funcName()
 ...
 end

 传参或返回值,都很自由

 function 可以作为参数被传递,也可以作为值被赋值给另一个变量
]] --

--c++
--void func(int a,int b){};
--void func(int a,int b){return a+b};

--lua
function Func1()
    print("this is func1")
end

Func1()

--传参
function Func2(a, b, c)
    print(a, b, c)
end

Func2(1, "lua", 'aa')

function Func3(a, b, c)
    print(1, 'a', "vb", 1, 3)
end

Func3()

--可变参
function Func5(...)
end

--函数当右值
--把匿名函数赋值给变量
Sum1 = function(a, b)
    return a + b
end

print(Sum1(10,20))

Sum2=Sum1

print(Sum2(100,200))

--当做其他函数的参数
function Func6(functionName,a,b)
    return functionName(a,b)
end

print(Func6(Sum1,1000,2000))

function Func7(a,b)
    return a+b
end

print(Func6(Func7,10000,20000))

输出结果:

this is func1
1       lua     aa
1       a       vb      1       3
30
300
3000
30000
PS D:\lua代码> 

6、基本数据类型三 : table

--[[

 基本数据类型
 Lua中有8中数据类型:nil boolean number string function table userdata thread

 table表,不是指数据库中的表,而是一种数据类型,类似于map,用k-v的方式实现,从理论上来讲,
 除了nil, 其他字符都可以作为k值(索引值)

 格式

 类似于hash
 TableName={
 k=v,
 }

 类似于数组 -- 下标从1开始
 TableName={
 x,
 y,
 z
 }

 可以用hash 格式和array 格式 混搭

 for 循环遍历
 for k,v in parirs(TableNmae) do
 print(k,v)
 end

 C++中的pairs是对组

 循环嵌套
 for k,v in paris(info3) do
 print(k,"==",v)
 if(type(v)=="table") then
 for k2,v2 in pairs(v) do
 print("\t",k2,"==",v2)
 end
 end
 end
]]--

table中类似哈希 k-v 表示方式:

--哈希表示方式
local info1={
    id=123,
    name="yyw",
    grade=60,
    sex="male"
}

for k,v in pairs(info1) do
    print(k,v)
end

-- local id
-- local name
-- local grade
-- local sex
-- local info2={
-- [id]=123,
-- [name]="yyw",
-- [grade]=60,
-- [sex]="male"
-- }

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

print("\n")

print(info1.id)
print(info1.name)
print(info1["sex"])

print("\n")

--增加字段
info1.age=123
info1["country"]="china"
info1["province"]="shanghai"

for k,v in pairs(info1) do
    print(k,v)
end

--删除字段
info1["sex"]=nil
info1.age=nil


print("\n")

for k,v in pairs(info1) do
    print(k,v)
end

--修改字段
info1["name"]="yywnb"
info1.id=456

print("\n")

for k,v in pairs(info1) do
    print(k,v)
end

输出结果:

sex     male
grade   60
id      123
name    yyw


123
yyw
male


province        shanghai
id      123
name    yyw
sex     male
country china
grade   60
age     123


province        shanghai
id      123
name    yyw
country china
grade   60


province        shanghai
id      456
name    yywnb
country china
grade   60


table中类似数组表示方式:

--数组表示方式,并且lua中数组下标是从1开始的
local info2={
    "yyw",
    123,
    true
}

print("\n")

for k,v in pairs(info2) do
    print(k,v)
end

--修改字段
info2[2]=234
info2[1]="yywnb"

print("\n")

for k,v in pairs(info2) do
    print(k,v)
end

--增加字段
info2[100]="contry"
info2[50]="province"

print("\n")

for k,v in pairs(info2) do
    print(k,v)
end

--删除字段
info2[1]=nil

print("\n")

for k,v in pairs(info2) do
    print(k,v)
end

输出结果:

1       yyw
2       123
3       true


1       yywnb
2       234
3       true


1       yywnb
2       234
3       true
100     contry
50      province


2       234
3       true
100     contry
50      province
PS D:\lua代码> 

hash 格式和array 格式 混搭:

--[[

    基本数据类型
        Lua中有8中数据类型:nil boolean number string function table userdata thread

        table表,不是指数据库中的表,而是一种数据类型,类似于map,用k-v的方式实现,从理论上来讲,
        除了nil, 其他字符都可以作为k值(索引值)

        格式

        类似于hash
        TableName={
            k=v,
        }

        类似于数组 -- 下标从1开始
        TableName={
            x,
            y,
            z
        }

        可以用hash 格式和array 格式 混搭

        for 循环遍历
        for k,v in parirs(TableNmae) do
            print(k,v)
        end

        C++中的pairs是对组

        循环嵌套
        for k,v in paris(info3) do
            print(k,"==",v)
            if(type(v)=="table") then
                for k2,v2 in pairs(v) do
                    print("\t",k2,"==",v2)
                end
            end
        end
]]--

--哈希表示方式
local info1={
    id=123,
    name="yyw",
    grade=60,
    sex="male"
}

for k,v in pairs(info1) do
    print(k,v)
end

-- local id
-- local name
-- local grade
-- local sex
-- local info2={
--     [id]=123,
--     [name]="yyw",
--     [grade]=60,
--     [sex]="male"
-- }

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

print("\n")

print(info1.id)
print(info1.name)
print(info1["sex"])

print("\n")

--增加字段
info1.age=123
info1["country"]="china"
info1["province"]="shanghai"

for k,v in pairs(info1) do
    print(k,v)
end

--删除字段
info1["sex"]=nil
info1.age=nil


print("\n")

for k,v in pairs(info1) do
    print(k,v)
end

--修改字段
info1["name"]="yywnb"
info1.id=456

print("\n")

for k,v in pairs(info1) do
    print(k,v)
end

print("\n")

--数组表示方式,并且lua中数组下标是从1开始的
local info2={
    "yyw",
    123,
    true
}

print("\n")

for k,v in pairs(info2) do
    print(k,v)
end

--修改字段
info2[2]=234
info2[1]="yywnb"

print("\n")

for k,v in pairs(info2) do
    print(k,v)
end

--增加字段
info2[100]="contry"
info2[50]="province"

print("\n")

for k,v in pairs(info2) do
    print(k,v)
end

--删除字段
info2[1]=nil

print("\n")

for k,v in pairs(info2) do
    print(k,v)
end

print("\n")
print("\n")


local info3 = {
    name = "tom",
    age = 23,
    sex = "woman",
    100,
    "abc",
    { "xyz", "def", son1_k_1 = "son1-key-1" },
    son2 = {
        son2_k_1 = "son2-key-1",
        name = "son2", false,
        "abc-son2", 123456
    },
    country = "china",
    100000
}

for k,v in pairs(info3) do
    print(k,"==",v)
    if(type(v)=="table") then
        for k2,v2 in pairs(v) do
            print("\t",k2,"==",v2)
        end
    end
end
print("\n")
print("\n")

--修改字段
info3[3][2]="DEF"
info3[3]["son1_k_1"]="SON1-KEY-1"
info3["son2"][1]=true
info3["son2"][2]="ABC-SON2"

for k,v in pairs(info3) do
    print(k,"==",v)
    if(type(v)=="table") then
        for k2,v2 in pairs(v) do
            print("\t",k2,"==",v2)
        end
    end
end
print("\n")

--删除字段
info3[3]=nil
info3[4]=nil

for k,v in pairs(info3) do
    print(k,"==",v)
    if(type(v)=="table") then
        for k2,v2 in pairs(v) do
            print("\t",k2,"==",v2)
        end
    end
end

print("\n")

--增加字段
info3[5]=100000
info3["province"]="shanghai"
info3["son2"][4]="lua"

for k,v in pairs(info3) do
    print(k,"==",v)
    if(type(v)=="table") then
        for k2,v2 in pairs(v) do
            print("\t",k2,"==",v2)
        end
    end
end

输出结果:

1       ==      100
2       ==      abc
3       ==      table: 000002591D9262A0
                1       ==      xyz
                2       ==      def
                son1_k_1        ==      son1-key-1
4       ==      100000
sex     ==      woman
country ==      china
son2    ==      table: 000002591D926EA0
                1       ==      false
                2       ==      abc-son2
                3       ==      123456
                name    ==      son2
                son2_k_1        ==      son2-key-1
name    ==      tom
age     ==      23




1       ==      100
2       ==      abc
3       ==      table: 000002591D9262A0
                1       ==      xyz
                2       ==      DEF
                son1_k_1        ==      SON1-KEY-1
4       ==      100000
sex     ==      woman
country ==      china
son2    ==      table: 000002591D926EA0
                1       ==      true
                2       ==      ABC-SON2
                3       ==      123456
                name    ==      son2
                son2_k_1        ==      son2-key-1
name    ==      tom
age     ==      23


1       ==      100
2       ==      abc
sex     ==      woman
country ==      china
son2    ==      table: 000002591D926EA0
                1       ==      true
                2       ==      ABC-SON2
                3       ==      123456
                name    ==      son2
                son2_k_1        ==      son2-key-1
name    ==      tom
age     ==      23


1       ==      100
2       ==      abc
son2    ==      table: 000002591D926EA0
                1       ==      true
                2       ==      ABC-SON2
                3       ==      123456
                4       ==      lua
                name    ==      son2
                son2_k_1        ==      son2-key-1
sex     ==      woman
province        ==      shanghai
country ==      china
5       ==      100000
name    ==      tom
age     ==      23
PS D:\lua代码> 

7、基本运算符(一)

--[[

 赋值=
 lua中变量时弱类型,就是说明声明变量时候不需要类型,其类型取决于所赋的值,
 并且,同一个变量,可以随时切换成不同的数据类型

 多重赋值

 a,b=b,a 交换,类似c,c++中的swap

 算符运算符
 加+、减-、乘\*,除/、取模%,指数(次方)^

 关系运算符
 等于==,不等于~=,大于>,小于<,大于或等于>=,小于或等于<=,
 关系运算符的运算结果只能是true 或者false,且只能在相同类型的数据间运算(运算时不会做隐式类型转换)

 对于对象型的数据(function,userdata,table),比较运算的知识引用,就是比较对象的地址
]]--

local a=1
local b=2
local c=a
print(a,b,c)
c="string"
print(c)
c=true
print(c)

local aa,bb,cc,dd=1,"abc",true
print(aa,bb,cc,dd)
aa,bb,cc=1,"true",{["aa"]=1,["bb"]=1}
print(aa,bb,cc)
tab={
    [aa]=1,
    [bb]=2
}
print(tab.aa,tab.bb)
tab={
    ["aa"]=1,
    ["bb"]=2
}
print(tab.aa,tab.bb)

local aaa,bbb=1,"string"
print(aaa,bbb)
local aaa,bbb=bbb,aaa
print(aaa,bbb)

print(10%3)
print(10%3.0)
print(10/3)
print(10/3.0)
print(2^10)

print(1==1)
print(1=="1")
print(1~="1")

local aaaa='1'
--print(1>="1") --err 语法错误
print(1+'1') --做了隐式类型转换
print(1+aaaa)

local tab3={
    ["ip"]="172.164",
    ["port"]="3306"
}
local tab2={
    ["name"]="lua"
}
print(tab3==tab2)
print(tab3.ip==tab2.name)
local tab4=tab3
print(tab4==tab3)
print(tab4==tab2)
print(tab3.ip==tab2.name)

输出结果:

1       2       1
string
true
1       abc     true    nil
1       true    table: 000002724B31A430
nil     nil
1       2
1       string
string  1
1
1.0
3.3333333333333
3.3333333333333
1024.0
true
false
true
2
2
false
false
true
false
false
PS D:\lua代码> 

8、基本运算符(二)

--[[
 逻辑运算符
 逻辑与 and、或 or、非 not
 && || !

 在lua中、逻辑运算与其他语言不是同一个意思、其运算结果返回值是参与运算的变量之一(not除外),
 not只返回true、false,在其他语言的逻辑运算、返回值是0或1(flase 或true),意思是返回一个bool值

 在lua中,只有nil(NULL,null)和false为假,其他都为真、包括空串或者0值

 对于and 和 or,实行短路运算(又称短路规则,短路求值,就是说,当前面的表达式可以返回时,就直接返回,不管后面的表达式)
]]--

--[[
 逻辑运算符
 逻辑与 and、或 or、非 not
 && || !

 在lua中、逻辑运算与其他语言不是同一个意思、其运算结果返回值是参与运算的变量之一(not除外),
 not只返回true、false,在其他语言的逻辑运算、返回值是0或1(flase 或true),意思是返回一个bool值

 在lua中,只有nil(NULL,null)和false为假,其他都为真、包括空串或者0值

 对于and 和 or,实行短路运算(又称短路规则,短路求值,就是说,当前面的表达式可以返回时,就直接返回,不管后面的表达式)
]]--

local a,b=1,2
print(a and b)  --如果a为真,则返回b

a=nil
print(a and b)  --如果a为假,则返回a
print("\n")

local c,d=1,false
print( c and d) --如果c为真,则返回d
c=nil
print(c and d)  --如果c为假,则返回c
print("\n")

local e,f=1,false
print(e or f)  --如果e为真,则返回e
e=nil
print(e or f)  --如果e为假,则返回f
print("\n")

local g,h=1,2
--print(g not h) --错误写法
print(not g)      --如果e为真,则返回假
print(not h)      --如果h为真,则返回假

local i= false
print(not i)      --如果i为假,则返回真
print("\n")

--用逻辑运算符or设置值
function func1(a,b)
    a= a or b
    b= a or b
    print(a,b)
end

func1()
func1(10,20)
print("\n")

--实现三目运算符 a=b?c:d 如果b=a为真,则值就是c,否则为d
local x,y,z=1,2,3
local u=(x and y) or z
print(u)

x=false
u=(x and y) or z
print(u)
print("\n")

local A,B,C=1,2,3
B=false
local D=(A and B) or C
print(D)

local E=((A and {B}) or {C})[1]  --这里才是一个合格的三目运算符
print(E)

输出结果:

2
nil


false
nil


1
false


false
false
true


nil     nil
10      10


2
3


3
false
PS D:\lua代码> 

9、流程控制 - 判断

--[[

 流程控制语句--判断
 if condition then
 ...
 end
]]--

local a,b=1,2
if(a==1) then
    print(a)
else
    print(b)
end

if a>=1 then
    print(b)
else
    print(a)
end

if a<1 then
    print("a<1")
else
    print("a>b")
end

local grade,score=60,90
if grade>=60 then
    print("well")
elseif grade<60 then
    print("fail")
elseif grade>60 and grade>=90 then
    print("good")
end

grade,score=60,90
if grade>60 then
    print("well")
elseif grade<60 then
    print("fail")
elseif grade>=60 and score>=90 then
    print("good")
end

if grade< 60 then
    print("fail")
elseif grade>=65 and grade<70 then
    print("well")
else
    if score>=90 then
        print("good")
    end
end

输出结果:

1
2
a>b
well
good
good
PS D:\lua代码> 

10、流程控制循环(一) ->while和repeat

--[[

 流程控制语句 循环

 while condition do
 statements
 end

 没有continue

 break只能跳出一次循环,跳出当前while循环语句

 goto FLAG 语句跳转到指定标记FLAG处,也可以用于跳出循环,FLAG是一个标记位,相当于一个锚点

 两者区别是
 break 只能跳出当前循环,而goto 可以跳转到指定位置,这样可以忽略一些代码

 在lua 中,没有这些运算符 i++, i--, ++i, --i, +=, -=

 a=b=1,lua中这种写法是错误的写法

 repeat
 --statements
 until condition

 while 和 repeat的区
 while循环中当条件不成立跳出循环
 repeat当条件成立时跳出循环
]]--

--求和1+...+100
--local i,sum=nil,nil
local i,sum=0,0
while i<100 do
    i=i+1
    sum=sum+i
end
print(i,sum)

i,sum=0,0
while i<100 do
    if i>49 then
        break
    end
    i=i+1
    sum=sum+i
end
print(i,sum)

i,sum=0,0
while i<100 do
    if i>49 then
        --break
        goto FLAG
    end
    i=i+1
    sum=sum+i
end

print(i,sum)

::FLAG::
print("lua")

i,sum=0,0
repeat
    i=i+1
    sum=sum+i
until i>=100

print(i,sum)

输出结果:

100     5050
50      1275
lua
100     5050
PS D:\lua代码> 

11、流程控制循环goto语句

--[[

 流程控制语句

 goto FLAG 语句,跳转到指定标记处,也可以用于跳出循环,FLAG是一个标记位,相当于一个锚点
 {
 int a;
 }
 代码块,作用域{}
 do
 ...
 end

 flag不可见原则
 1、不能从外面goto到代码块里面,因为代码块里面的flag对于外面的goto语句来说是不可见的
 2、不能跳出或者跳入一个函数,因为函数也是一个block块
 3、不能跳入本地变量(local)作用域
]]--

--死循环
-- local i=0
-- ::FLAG10::
-- print(i)
-- i=i+1
-- goto FLAG10

print(1234)
goto FLAG13
--goto FLAG11 --err 标签`FLAG11`不可见
--goto FLAG13 --err 标签`FLAG12`不可见
do
    print("a")
    print("b")
    ::FLAG11::
    print("c")
    print("d")
    ::FLAG12::
end

::FLAG13::
print("aa")
print("bb")
print("cc")
::FLAG14::
print("dd")
print("\n")


function func1()
    ::FLAG3::
    print( "func1-11")
    print( "func1--22")
    --goto FLAG6 err 标签`FLAG6`不可见
    goto FLAG5
    ::FLAG4::

    print("func1--33")
    ::FLAG5::
end

-- goto FLAG3 err 标签`FLAG3`不可见
::FLAG6::
print("aaaa")
func1()
-- goto FLAG4 --FLAG4 err 标签`FLAG3`不可见
::FLAG7::
print("bbbb")


do
    a=123
    ::FLAG1::
    --print(a)
    ::FLAG2::
    --goto FLAG3 --此处goto是在local b的作用域外面,使用报错
    local b=456
    ::FLAG3::
    --print(b)
    goto FLAG3   --此处goto是在local b的作用域里面
end
--print(a)
--print(b)


输出结果:

1234
aa  
bb  
cc  
dd  
    
    
aaaa
func1-11
func1--22
bbbb


12、流程控制循环(二) ->数值for和范围for ipairs

--[[
 流程控制语句

 for循环分为数值循环和泛型循环(类似foreach)

 数值循环
 for 变量名=初始值,结束值,步长(默认为1,可以省略) do
 ...
 end

 泛型循环
 for k,v in 迭代函数(table) do --此处v可以省略,k不能省略
 ...
 end

 迭代函数 pairs(table) ipairs(table)

 ipairts(table) 顺序遍历,中间的序号会断开,遇到 k==v 直接跳过
 ,遇到第一个nil会终止遍历,一般情况下,ipairs(table)用于数组
 类型的集合遍历
]]--


for i=1,10 do
    io.write(i," ")
end
print("\n")

for i=1,10,2 do
    io.write(i," ")
end
print("\n")

for i=1,10,3 do
    io.write(i," ")
end
print("\n")

for i=10,1,-2 do
    io.write(i," ")
end
print("\n")

local tab1={
    11,
    22,
    33,
    44,
    55
}
for i=1,#tab1 do
    io.write(tab1[i]," ")
end
io.write("\n")

for i=1,10 do
    print(tab1[i])
end
io.write("\n")


tab2={
    11,
    22,
    "xxx",
    44,
    ["key"]=vvv,
    "nil",
    key2="vvv",
    nil,
    55
}
for k,v in ipairs(tab2) do
    print(k,v)
end

-- for k,v in ipairs(tab2) do
-- tab2[k]=v\*10
-- end
for k,v in ipairs(tab2) do
    print(k,v)
end

输出结果:

1 2 3 4 5 6 7 8 9 10 

1 3 5 7 9

1 4 7 10

10 8 6 4 2

11 22 33 44 55
11
22
33
44
55
nil
nil
nil
nil
nil

1       11
2       22
3       xxx
4       44
5       nil
1       11
2       22
3       xxx
4       44
5       nil
PS D:\lua代码> 

13、流程控制循环(三) -> pairs

--[[
    流程控制语句

    for循环分为数值循环和泛型循环(类似foreach)

    数值循环
    for 变量名=初始值,结束值,步长(默认为1,可以省略) do
        ...
    end

    泛型循环
    for k,v in 迭代函数(table) do  --此处v可以省略,k不能省略
        ...
    end

    迭代函数 pairs(table) ipairs(table)

    ipairts(table) 顺序遍历,中间的序号会断开,遇到 k==v 直接跳过
    ,遇到第一个nil会终止遍历,一般情况下,ipairs(table)用于数组
    类型的集合遍历,而且遍历的是数组下标从1开始不能是负数下标,
    如果是负数下标的话跳过负数下标

    pairs(tbale) 遇到nil会跳过,同时适用于数组类型和 k==v 类型的集合,
    混搭没有问题,如果是混搭的时候,会优先获取数组类型数据

    paris的适用范围大于ipairs,类似iparis是pairs的子集
    如果使用时不确定选择哪个,无脑pairs

]]--

local tab1={
    11,
    nil,
    "abc",
    22,
    "lua",
    33,
    44,
    55
}

for k,v in pairs(tab1) do
    print(k,v)
end
print("\n")

local tab2={
    11,
    id=123,
    22,
    name="tom",
    age=456,
    33,
    conuty="china",
    nil,
    "abc",
    44,
    ["province"]="shanghai",
    55
}
for k,v in pairs(tab2) do
    print(k,v)
end

for i=1,9 do
    for j=1,i do
        io.write(i,"\*",j,"=",i\*j,"\t")
    end
    print("\n")
end

输出结果:

1       11
3       abc
4       22
5       lua
6       33
7       44
8       55


1       11
2       22
3       33
5       abc
6       44
7       55
conuty  china
name    tom
province        shanghai
id      123
age     456
1\*1=1

2\*1=2   2\*2=4

3\*1=3   3\*2=6   3\*3=9

4\*1=4   4\*2=8   4\*3=12  4\*4=16

5\*1=5   5\*2=10  5\*3=15  5\*4=20  5\*5=25

6\*1=6   6\*2=12  6\*3=18  6\*4=24  6\*5=30  6\*6=36

7\*1=7   7\*2=14  7\*3=21  7\*4=28  7\*5=35  7\*6=42  7\*7=49

8\*1=8   8\*2=16  8\*3=24  8\*4=32  8\*5=40  8\*6=48  8\*7=56  8\*8=64

9\*1=9   9\*2=18  9\*3=27  9\*4=36  9\*5=45  9\*6=54  9\*7=63  9\*8=72  9\*9=81

PS D:\lua代码> 

14、table -> array

--[[
 table
 array
 hash
]]--

--自定义下标不建议这样使用
local tab1={
    11,
    22,
    33,
    "string"
}
tab1[55]="lua"

for k,v in ipairs(tab1) do
    print(k,v)
end
print("\n")
for k,v in pairs(tab1) do
    print(k,v)
end
print("\n")

local tab2={}
for i=-4,4 do
    tab2[i]=i\*10
end

for k,v in ipairs(tab2) do  --遍历的是数组下标从1开始不能是负数下标,如果是负数下标的话跳过负数下标
    print(k,v)
end
print("\n")
for k,v in pairs(tab2) do
    print(k,v)
end
print("\n")

--二维数组
local x={
    11,
    22,
    33
}
local y={
    44,
    55,
    66
}
local tab3={
    {
        11,
        22,
        33
    },
    {
        44,
        55,
        66
    }
}

for i=1,2 do
    for j=1,3 do
        print(i,j,tab3[i][j])
    end
    print("\n")
end
print("\n")

for k,v in ipairs(tab3) do
    for k2,v2 in ipairs(v) do
        print(k,k2,v2)
    end
    print("\n")
end
print("\n")

for k,v in pairs(tab3) do
    for k2,v2 in pairs(v) do
        print(k,k2,v2)
    end
    print("\n")
end
print("\n")

--自己创建一个二维数组
local tab4={}
for i=1,3 do
    tab4[i]={}  --因为是二维数组,所以tab4[i]={}一定要
    for j=1,2 do
        tab4[i][j]=i\*j\*10
    end
end

for k,v in ipairs(tab4) do
    for k2,v2 in ipairs(v) do
        print(k,k2,v2)
    end
    print("\n")
end


输出结果:

1       11
2       22
3       33
4       string


1       11
2       22
3       33
4       string
55      lua


1       10
2       20
3       30
4       40


1       10
2       20
3       30
4       40
-2      -20
-1      -10
-4      -40
-3      -30
0       0


1       1       11
1       2       22
1       3       33


2       1       44
2       2       55
2       3       66




1       1       11
1       2       22
1       3       33


2       1       44
2       2       55
2       3       66




1       1       11
1       2       22
1       3       33


2       1       44
2       2       55
2       3       66




1       1       10
1       2       20


2       1       20
2       2       40


3       1       30
3       2       60


PS D:\lua代码> 

15、table操作函数

--[[
 ---@param list table
 ---@param sep? string
 ---@param i? integer
 ---@param j? integer
 ---@return string
 ---@nodiscard
 function table.concat(list, sep, i, j) end
 ---提供一个列表,其所有元素都是字符串或数字,返回字符串 `list[i]..sep..list[i+1] ··· sep..list[j]`。

 ---@param list table
 ---@param pos? integer
 ---@return any
 function table.remove(list, pos) end
 ---移除 `list` 中 `pos` 位置上的元素,并返回这个被移除的值。默认不写pos是最后一个位置


 ---
 ---[查看文档](command:extension.lua.doc?["en-us/54/manual.html/pdf-table.insert"])
 ---
 ---@overload fun(list: table, value: any)
 ---@param list table
 ---@param pos integer
 ---@param value any
 function table.insert(list, pos, value) end
 ---在 `list` 的位置 `pos` 处插入元素 `value`。


 ---
 ---[查看文档](command:extension.lua.doc?["en-us/54/manual.html/pdf-table.sort"])
 ---
 ---@generic T
 ---@param list T[]
 ---@param comp? fun(a: T, b: T):boolean
 ---function table.sort(list, comp)
 ---在表内从 `list[1]` 到 `list[#list]` \*原地\* 对其间元素按指定次序排序。


 ---将元素从表 `a1` 移到表 `a2`。
 ---```lua
 ---a2[t],··· =
 ---a1[f],···,a1[e]
 ---return a2
 ---```
 ---
 ---
 ---
 ---@param a1 table
 ---@param f integer
 ---@param e integer
 ---@param t integer
 ---@param a2? table
 ---@return table a2
 function table.move(a1, f, e, t, a2) end
]]--

--table.concat(table, sep, i, j),将表中的元素拼接成一个字符串,sep是连接符号,i是起始位置,j是终止位置
--table.remove(list, pos)移除 `list` 中 `pos` 位置上的元素,并返回这个被移除的值。默认不写pos是最后一个位置
--table.insert(list, pos, value) 在 `list` 的位置 `pos` 处插入元素 `value`。默认不写pos是在最后一个位置插入
--table.sort(list, comp) 数组排序,默认从小到大,可自定义排序规则
--table.move(a1, f, e, t, a2) 把数组a1中的元素往a2中拷贝

local tab1={
   "abc",
   "DEF",
   "123",
   11,
   ["key"]=value,
   ["id"]=123
}
print(table.concat(tab1))
print(table.concat(tab1,"--"))
print(table.concat(tab1,"--",2,3))
print(table.concat(tab1,"--",1,2))
print("\n")

print(table.remove(tab1))
print(table.concat(tab1))
print(table.remove(tab1,1))
print(table.concat(tab1))
print("\n")

print(table.insert(tab1,"china"))
print(table.concat(tab1))
print("\n")

table.sort(tab1)
print(table.concat(tab1))
print("\n")

function cmp(a,b)
    return a>b
end
table.sort(tab1,cmp)
print(table.concat(tab1))
print("\n")

local tab2={
    "a",
    "b"
}

table.move(tab1,1,2,3,tab2)  --3指定是第二个表tab2中的位置,这里就是第三个位置,1和2代表tab1中的第一个元素开始和结束就是chinaDEF
print(table.concat(tab1))
print(table.concat(tab2))
print("\n")


--下面的两种写法表示一样的效果,没区别
local info1={
    id=123,
    name="lua",
    grade=60,
    sex="male"
}
local info2={
    ["id"]=123,
    ["name"]="lua",
    ["grade"]=60,
    ["sex"]="male"
}

输出结果:

abcDEF12311
abc--DEF--123--11
DEF--123
abc--DEF


11
abcDEF123
abc
DEF123



DEF123china


123DEFchina


chinaDEF123


chinaDEF123
abchinaDEF


PS D:\lua代码> 

16、string常用api

--[[
    ---
    ---接收一个字符串,将其中的小写字符都转为大写后返回其副本。
    ---
    ---[查看文档](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.upper"])
    ---
    ---@param s string
    ---@return string
    ---@nodiscard
    function string.upper(s) end

    return string

    ---
    ---将其中的大写字符都转为小写后返回其副本。
    ---
    ---[查看文档](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.lower"])
    ---
    ---@param s string
    ---@return string
    ---@nodiscard
    function string.lower(s) end

    return string

    ---
    ---返回其长度。
    ---
    ---[查看文档](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.len"])
    ---
    ---@param s string
    ---@return integer
    ---@nodiscard
    function string.len(s) end

    return number

    ---
    ---返回字符串 s 的翻转串。
    ---
    ---[查看文档](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.reverse"])
    ---
    ---@param s string
    ---@return string
    ---@nodiscard
    function string.reverse(s) end

    return string

    ---
    ---返回字符串的子串, 该子串从 `i` 开始到 `j` 为止。
    ---
    ---[查看文档](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.sub"])
    ---
    ---@param s  string
    ---@param i  integer
    ---@param j? integer
    ---@return string
    ---@nodiscard
    function string.sub(s, i, j) end

    return string

    ---
    ---查找第一个字符串中匹配到的 `pattern`(参见 [§6.4.1](command:extension.lua.doc?["en-us/54/manual.html/6.4.1"]))。
    ---
    ---
    ---@param s       string
    ---@param pattern string
    ---@param init?   integer
    ---@param plain?  boolean
    ---@return integer start
    ---@return integer end
    ---@return any ... captured
    ---@nodiscard
    function string.find(s, pattern, init, plain) end

    return number

    ---
    ---将字符串 s 中,所有的(或是在 n 给出时的前 n 个) pattern (参见 [§6.4.1](command:extension.lua.doc?["en-us/54/manual.html/6.4.1"]))都替换成 repl ,并返回其副本。
    ---
    ---[查看文档](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.gsub"])
    ---
    ---@param s       string
    ---@param pattern string
    ---@param repl    string|number|table|function
    ---@param n?      integer
    ---@return string
    ---@return integer count
    ---@nodiscard
    function string.gsub(s, pattern, repl, n) end

    return string

    ---
    ---接收零或更多的整数。 返回和参数数量相同长度的字符串。 其中每个字符的内部编码值等于对应的参数值。
    ---
    ---[查看文档](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.char"])
    ---
    ---@param byte integer
    ---@param ... integer
    ---@return string
    ---@nodiscard
    function string.char(byte, ...) end

    return string

    ---
    ---返回字符 `s[i]`, `s[i+1]`, ... ,`s[j]` 的内部数字编码。
    ---
    ---[查看文档](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.byte"])
    ---
    ---@param s  string
    ---@param i? integer
    ---@param j? integer
    ---@return integer ...
    ---@nodiscard
    function string.byte(s, i, j) end

    return number
]]--

local str1="abCD1234"
local str2=string.upper(str1)  --接收一个字符串,将其中的小写字符都转为大写后返回其副本。
print(str2)
local str3=string.lower(str1)  --接收一个字符串,将其中的大写字符都转为小写后返回其副本。
print(str3)
print("\n")

print(string.len(str1))        --接收一个字符串,返回其长度。
print(string.len("你好1bc a")) --其中一个汉字是3个字符,总共11个字符
print("\n")

print(string.reverse(str1))    --接收一个字符串,返回字符串 s 的翻转串。
print("\n")

local a=0000
print("china".." is".." best".." country!".." str1"..1 ..1 ..a..2)               -- .. 连接符,number 如果在连接符左边,后面要空格
print("\n")

print(string.sub(str1,2))      --返回字符串的子串, 该子串从 `i` 开始到 `j` 为止。默认有两个参数
print(string.sub(str1,1,2))
print(string.sub(str1,-4,-2))  --负数是从右往左数
print("\n")

print(string.find(str1,1))        -- 在字符串s中 查找pattern(可以是表达式),如果找到,则返回pattern 第一次出现的开始位置和结束位置,如果没找到,返回nil
print(string.find(str1,"abC"))
print(string.find(str1,"ab",3))      --从指定位置开始寻找
print(string.find(str1,"ab",3,5))
print(string.find(str1,"ab",-8))     --负数是从右往左数
print("\n")

print(string.find(str1,"%d",1));     --最后一个参数,默认就是false,开启正则匹配模式,这里寻找的是%d number型
print(string.find(str1,"(%d%d%d%d)"))
print(string.find(str1,"%d",6,true));--最后一个参数,true 是直接当子串处理
print("\n")

print(string.gsub(str1,1,2))         --全部替换
print(string.gsub(str1,"ab","AB",2)) --最多替换两次
print("\n")

print(string.char(65))               --asscil码转字符,数字只能是0~255
print(string.byte("a"))              --字符转asscil码
print(string.byte("abc",1,2));       --1和2代表转几个
print(string.byte("abc",1,3));

输出结果:

ABCD1234
abcd1234


8
11


4321DCba


china is best country! str11102


bCD1234
ab
123


5       5
1       3
nil
nil
1       2


5       5
5       8       1234
nil


abCD2234        1
ABCD1234        1


A
97
97      98
97      98      99
PS D:\lua代码> 

17、function常见表示形式

--[[

    function进阶,常见的表现形式
        --函数普通函数

        --函数当右值,赋值给一个变量

        --匿名函数当右值

        --函数当参数

        --函数当返回值

        --匿名函数当返回值

        --函数多返回值
]]--

--普通函数
function show(a,b)
    print(a,b)
end
--函数直接调用
show("abc",123)

--函数当右值,赋值给一个变量
func1=show
func1("abc",123)

--匿名函数当右值
func2=function(a,b)
    print("abc",123)
end
func2()

--函数当参数
function func3(func,a,b)
    func(a,b)
end
func3(show,"abc",123)
func3(
    function(a, b)
        print(a, b)
    end, 
    "abc", "123"
)
print("\n")

--函数当返回值
function func4()
    return func1
end
fun1=func4()
fun1("abc",123)
func4()("abc",123)

--匿名函数当返回值
function func5()
    return function(a,b)
        print(a,b)
    end
end
fun2=func5()
fun2("abc",123)
func5()("abc",123)
print("\n")

--函数多返回值
function func6()
    function func6\_son1(a,b)
        print("son1",a,b)
    end
    function func6\_son2(a,b)
        print("son2",a,b)
    end
    return func6_son1,
    func6_son2,
    func1,
    function(a,b)
        print("son\_last",a,b)
    end
end

fun3,fun4,fun5,fun6=func6()
fun4("abc",123)
fun5("abc",123)
fun6("abc",123)
fun3("abc",123)


输出结果:

abc     123
abc     123
abc     123
abc     123
abc     123


abc     123
abc     123
abc     123
abc     123


son2    abc     123
abc     123
son_last        abc     123
son1    abc     123
PS D:\lua代码> 

18、table中的function

--[[

 function进阶,table中的function

]]--

function show(a)
    print(a)
end

local tab1={
    t1_show=show,
    add=function(a,b)
        return a+b
    end
}
tab1.sub=function(a,b)
    return a-b
end
tab1["mul"]=function(a,b)
    return a\*b
end
tab1["div"]=function(a,b)
    return a/b
end

tab1.t1\_show("abc")
tab1.t1\_show(tab1.add(11,22))
tab1["t1\_show"](123)
tab1.t1\_show(tab1.sub(11,22))
tab1.t1\_show(tab1.mul(11,22))
tab1.t1\_show(tab1.div(11,22))
print("\n")

calc={
    add=function(a,b)
        return a+b
    end,
    sub=function(a,b)
        return a-b
    end,
    mul=function(a,b)
        return a\*b
    end,
    sub=function(a,b)
        return a/b
    end,
    show=function(a)
        print(a)
    end
}

calc.show(calc.add(11,22))
calc.show(calc.sub(11,22))
calc.show(calc.mul(11,22))
calc.show(calc.sub(11,22))

tab2={
    a=0,
    b=0,
    result=0,
    add=function()
        tab2.result=tab2.a+tab2.b
    end,
    sub=function()
        tab2.result=tab2.a-tab2.b
    end,
    mul=function()
        tab2.result=tab2.a\*tab2.b
    end,
    div=function()
        tab2.result=tab2.a/tab2.b
    end,
    show=function()
        print (tab2.result)
    end
}

tab2.a=11
tab2.b=22
tab2.add()
tab2.show()


输出结果:

abc
33
123
-11
242
0.5


33
0.5
242
0.5

33
0.5
242
0.5
33

19、用select处理可变参数

--[[

    关于用select处理可变参数

    select(n,...),表示获取可变参数的一部分数据从n开始
    select("#",...),表示获取可变参数的个数

     ---
    ---接收任意数量的参数,并将它们的值打印到 `stdout`。 它用 `tostring` 函数将每个参数都转换为字符串。 
    --`print` 不用于做格式化输出。仅作为看一下某个值的快捷方式。 多用于调试。 
    --完整的对输出的控制,请使用 [string.format](command:extension.lua.doc?["en-us/54/manual.html/pdf-string.format"])
    -- 以及 [io.write](command:extension.lua.doc?["en-us/54/manual.html/pdf-io.write"])。
    ---
    ---[查看文档](command:extension.lua.doc?["en-us/54/manual.html/pdf-print"])
    ---

    ---
    ---如果 `index` 是个数字, 那么返回参数中第 `index` 个之后的部分; 负的数字会从后向前索引(`-1` 指最后一个参数)。 
    --否则,`index` 必须是字符串 `"#"`, 此时 `select` 返回参数的个数。
    ---
    ---[查看文档](command:extension.lua.doc?["en-us/54/manual.html/pdf-select"])
    ---
    ---@param index integer|'"#"'
    ---@return any
    ---@nodiscard
    function select(index, ...) end

]]--

local function func1(...)
    print(select(1,...))
    print(select(2,...))
    print(select(3,...))
    print(select(4,...))
    print(select(5,...))
    print(select("#",...))

    local sum=0
    local count=select("#",...)
    for i=1,count do
        sum=sum+(select(i,...))
    end
    return sum
end

print(func1(11,22,33,44,55))
print("\n")

local function func2()
    return 11,22,33
end

local function func3()
    return 111,222,333
end

print(func2())
print(func3())
print("\n")
print((func2()))
print((func3()))
print("\n")
print(func2(),"===",func3())
print((func2()),"===",func3())

输出结果:

11      22      33      44      55
22      33      44      55
33      44      55
44      55
55
5
165


11      22      33
111     222     333


11
111


11      ===     111     222     333
11      ===     111     222     333
PS D:\lua代码> 

20、用pack处理可变参数

--[[

    ---用pack 处理函数可变参数
    ---table.pack(...) 将可变参打包成一个table,且会在最后多出一个n键,其对应的值是可变参的参数个数
    ---table.unpack(list, i, j) 解包,将table 解成可变参

    ---
    ---返回用所有参数以键 `1`,`2`, 等填充的新表, 并将 `"n"` 这个域设为参数的总数。
    ---
    ---[查看文档](command:extension.lua.doc?["en-us/54/manual.html/pdf-table.pack"])
    ---
    ---@return table
    ---@nodiscard
    function table.pack(...) end

    ---
    ---返回列表中的元素。 这个函数等价于
    ---```lua
    ---    return list[i], list[i+1], ···, list[j]
    ---```
    ---i 默认为 1 ,j 默认为 #list。
    ---
    ---
    ---[查看文档](command:extension.lua.doc?["en-us/54/manual.html/pdf-table.unpack"])
    ---
    ---@generic T
    ---@param list T[]
    ---@param i?   integer
    ---@param j?   integer
    ---@return T   ...
    ---@nodiscard
    function table.unpack(list, i, j) end
]]--

local function func1(...)
    print(table.pack(...).n)

    local sum=0
    local tab1=table.pack(...)
    for k,v in pairs(tab1) do
        if k~="n" then
            sum=sum+v
        end
    end

    local count=tab1.n
    print(count)
    for i=1,count do
        if tab1[i]~=nil then
            sum=sum+tab1[i]
        end
    end

    return sum
end

print(func1(11,22,nil,33,44,55,nil))
print("\n")

local function func2()
    --return 11,22,33,44,55,66
    return table.pack(11,22,33,44,55,66)
end

print(11,22,33,44,55,66)
print(func2())
print(table.unpack(func2()))
print(table.unpack(func2(),1,2))
print("\n")

local tab2=func2()
print(table.unpack(tab2))
print("\n")

---可变参转成table
local function func3(...)
    local sum=0
    local tab1={...}
    local count=#tab1
    print(count)
    for k,v in pairs(tab1) do
        if k~="nil" then
            sum=sum+v
        end
        print(k,v)
    end
    return sum
end

print(func3(11,22,nil,33,44,nil,55,66,77))

输出结果:

7
7
330


11      22      33      44      55      66
table: 000001926BF91DE0
11      22      33      44      55      66
11      22


11      22      33      44      55      66


9
1       11
2       22
4       33
5       44
7       55
8       66
9       77
308
PS D:\lua代码> 

21、lua中闭包 (closure)的实现

--[[

 闭包

 百度百科 https://baike.baidu.com/item/闭包/10908873

 闭包就是能够读取其他函数内部变量的函数。
 例如在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。
 在本质上,闭包是将函数内部和函数外部连接起来的桥梁。

 lua
 当一个函数内部嵌套另一个函数定义时,内部的函数体可以访问外部的函数的局部变量,
 这种特征在lua中我们称作词法定界。
 虽然这看起来很清楚,事实并非如此。
 词法定界加上第一类函数在编程语言里是一个功能强大的概念,很少语言提供这种支持。

 个人理解
 闭包就是指一种编码方式,一种思想,而不是指某种具体的技术或函数或库

 内部函数读取外部函数的变量

 lambda 表达式,经典的闭包表现方式之一

]]--

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8m1N0Ihi-1665330518835)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20221004001207777.png)]

local function func1(a,b)
    local x=0
    local y=0
    return function()
        x=x+1           --类似static属性,内部匿名函数访问外部函数func1的变量x
        print(a,b,x,y)
    end
end

func1("abc",123)()
print("\n")

local tmp1=func1("abc",123)
tmp1()
tmp1()
tmp1()
tmp1()
print("\n")

local tmp2=func1("abc",123)
tmp2()

输出结果:

abc     123     1       0


abc     123     1       0
abc     123     2       0
abc     123     3       0
abc     123     4       0


abc     123     1       0
PS D:\lua代码> 

22、用闭包 (closure)实现ipairs迭代器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NaoNqpue-1665330518835)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20221004002633436.png)]


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f2KRhXAO-1665330518836)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20221004003844556.png)]

--[[

    迭代器

    百科百科 https://baike.baidu.com/item/迭代器

    迭代器(iterator)有时又称光标(cursor)是程序设计的软件设计模式,
    可在容器对象(container,例如链表或数组)上遍访的接口,
    设计人员无需关心容器对象的内存分配的实现细节。


    ---
    ---如果 `t` 有元方法 `__pairs`, 以 `t` 为参数调用它,并返回其返回的前三个值。
    ---
    ---否则,返回三个值:`next` 函数, 表 `t`,以及 `nil`。 因此以下代码
    ---```lua
    ---    for k,v in pairs(t) do body end
    ---```
    ---能迭代表 `t` 中的所有键值对。
    ---
    ---参见函数 [next](command:extension.lua.doc?["en-us/54/manual.html/pdf-next"]) 中关于迭代过程中修改表的风险。
    ---
    ---
    ---[查看文档](command:extension.lua.doc?["en-us/54/manual.html/pdf-pairs"])
    ---
    ---@generic T: table, K, V
    ---@param t T
    ---@return fun(table: table<K, V>, index?: K):K, V
    ---@return T
    function pairs(t) end

    ---
    ---返回三个值(迭代函数、表 `t` 以及 `0` ), 如此,以下代码
    ---```lua
    ---    for i,v in ipairs(t) do body end
    ---```
    ---将迭代键值对 `(1,t[1]) ,(2,t[2]), ...` ,直到第一个空值。
    ---
    ---
    ---[查看文档](command:extension.lua.doc?["en-us/54/manual.html/pdf-ipairs"])
    ---
    ---@generic T: table, V
    ---@param t T
    ---@return fun(table: V[], i?: integer):integer, V
    ---@return T
    ---@return integer i
    function ipairs(t) end
]]--

local tab1={
    11,
    22,
    33,
    nil,
    ["string"]="lua",
    44,
    nil,
    55
}

for k,v in pairs(tab1) do
    print(k,v)
end
print("\n")

for k,v in ipairs(tab1) do
    print(k,v)
end
print("\n")

local function MyIpairs(tab1)
    local count=#tab1
    local index=0

    return function()
        if index <= count then
            index=index+1
            if tab1[index]~=nil then
                return index,tab1[index]
            end
        end
    end
end

local function MyPairs(tab1)
    local count=#tab1
    local index=0

    return function()
        if index<=count then
            index=index+1
            -- if tab1[index]~=nil then
            -- return index,tab1[index]
            -- else
            -- index=index+1
            -- return index,tab1[index]
            -- end
            if tab1[index] == nil then
                index=index+1
            end
            return index,tab1[index]
        end
    end
end


for k,v in MyIpairs(tab1) do
    print(k,v)
end
print("\n")

for k,v in MyPairs(tab1) do
    print(k,v)
end

输出结果:

1       11
2       22
3       33
5       44
7       55
string  lua


1       11
2       22
3       33


1       11
2       22
3       33


1       11
2       22
3       33
5       44
7       55
9       nil
PS D:\lua代码> 

23、元表和元方法(一)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2E3VOrse-1665330518837)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20221004213130240.png)]

--[[

 元表 metatable

 元表并不是一个普通的表,而是一套自定义的计算规则,用这些规则,可以实现表与表之间的运算
 而这些规则,都以函数的方式,写在元表中,所以又称为元方法(就是写在元表里面的方法)

 起到一个类似于其它语言中的运算符重载的作用


 setmetatable(table, metatable) -- 将 metatable 设为 table 的元表,其返回值为table

 ---
 ---给指定表设置元表。 (你不能在 Lua 中改变其它类型值的元表,那些只能在 C 里做。
 ---如果 `metatable` 是 `nil`, 将指定表的元表移除。 如果原来那张元表有 `"\_\_metatable"` 域,抛出一个错误。
 ---
 ---
 ---[查看文档](command:extension.lua.doc?["en-us/54/manual.html/pdf-setmetatable"])
 ---
 ---@param table table
 ---@param metatable? table
 ---@return table
 function setmetatable(table, metatable) end
]]--

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

—查看文档

—@generic T: table, K, V
—@param t T
—@return fun(table: table<K, V>, index?: K):K, V
—@return T
function pairs(t) end

---
---返回三个值(迭代函数、表 `t` 以及 `0` ), 如此,以下代码
---```lua
---    for i,v in ipairs(t) do body end
---```
---将迭代键值对 `(1,t[1]) ,(2,t[2]), ...` ,直到第一个空值。
---
---
---[查看文档](command:extension.lua.doc?["en-us/54/manual.html/pdf-ipairs"])
---
---@generic T: table, V
---@param t T
---@return fun(table: V[], i?: integer):integer, V
---@return T
---@return integer i
function ipairs(t) end

]]–



local tab1={
11,
22,
33,
nil,
[“string”]=“lua”,
44,
nil,
55
}

for k,v in pairs(tab1) do
print(k,v)
end
print(“\n”)

for k,v in ipairs(tab1) do
print(k,v)
end
print(“\n”)

local function MyIpairs(tab1)
local count=#tab1
local index=0

return function()
    if index <= count then
        index=index+1
        if tab1[index]~=nil then
            return index,tab1[index]
        end
    end
end

end

local function MyPairs(tab1)
local count=#tab1
local index=0

return function()
    if index<=count then
        index=index+1
        -- if tab1[index]~=nil then
        -- return index,tab1[index]
        -- else
        -- index=index+1
        -- return index,tab1[index]
        -- end
        if tab1[index] == nil then
            index=index+1
        end
        return index,tab1[index]
    end
end

end

for k,v in MyIpairs(tab1) do
print(k,v)
end
print(“\n”)

for k,v in MyPairs(tab1) do
print(k,v)
end


输出结果:



1 11
2 22
3 33
5 44
7 55
string lua

1 11
2 22
3 33

1 11
2 22
3 33

1 11
2 22
3 33
5 44
7 55
9 nil
PS D:\lua代码>


## 23、元表和元方法(一)


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2E3VOrse-1665330518837)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20221004213130240.png)]



–[[

元表 metatable

元表并不是一个普通的表,而是一套自定义的计算规则,用这些规则,可以实现表与表之间的运算
而这些规则,都以函数的方式,写在元表中,所以又称为元方法(就是写在元表里面的方法)

起到一个类似于其它语言中的运算符重载的作用

setmetatable(table, metatable) – 将 metatable 设为 table 的元表,其返回值为table


—给指定表设置元表。 (你不能在 Lua 中改变其它类型值的元表,那些只能在 C 里做。
—如果 metatablenil, 将指定表的元表移除。 如果原来那张元表有 "\_\_metatable" 域,抛出一个错误。


—查看文档

—@param table table
—@param metatable? table
—@return table
function setmetatable(table, metatable) end
]]–





[外链图片转存中...(img-OG3RmtIs-1715439311176)]
[外链图片转存中...(img-SLA0grOf-1715439311176)]

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 20
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值