Java最新lua脚本世界--快速入门,字节跳动Java架构师学习笔记

总结

我们总是喜欢瞻仰大厂的大神们,但实际上大神也不过凡人,与菜鸟程序员相比,也就多花了几分心思,如果你再不努力,差距也只会越来越大。实际上,作为程序员,丰富自己的知识储备,提升自己的知识深度和广度是很有必要的。

Mybatis源码解析

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

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

then

–[ 在布尔表达式 2 为 true 时执行该语句块 --]

elseif( 布尔表达式 3)

then

–[ 在布尔表达式 3 为 true 时执行该语句块 --]

else

–[ 如果以上布尔表达式都不为 true 则执行该语句块 --]

end

实例

以下实例对变量 a 的值进行判断:

–[ 定义变量 --]

a = 100

–[ 检查布尔条件 --]

if( a == 10 )

then

–[ 如果条件为 true 打印以下信息 --]

print(“a 的值为 10” )

elseif( a == 20 )

then

–[ if else if 条件为 true 时打印以下信息 --]

print(“a 的值为 20” )

elseif( a == 30 )

then

–[ if else if condition 条件为 true 时打印以下信息 --]

print(“a 的值为 30” )

else

–[ 以上条件语句没有一个为 true 时打印以下信息 --]

print(“没有匹配 a 的值” )

end

print("a 的真实值为: ", a )

以上代码执行结果如下:

没有匹配 a 的值

a 的真实值为: 100

if 嵌套语句

实例

–[ 定义变量 --]

a = 100;

b = 200;

–[ 检查条件 --]

if( a == 100 )

then

–[ if 条件为 true 时执行以下 if 条件判断 --]

if( b == 200 )

then

–[ if 条件为 true 时执行该语句块 --]

print(“a 的值为 100 b 的值为 200” );

end

end

print(“a 的值为 :”, a );

print(“b 的值为 :”, b );

结果

a 的值为 100 b 的值为 200

a 的值为 : 100

b 的值为 : 200

八、Lua 函数!!!


在Lua中,函数是对语句和表达式进行抽象的主要方法。既可以用来处理一些特殊的工作,也可以用来计算一些值。

Lua 提供了许多的内建函数,你可以很方便的在程序中调用它们,如print()函数可以将传入的参数打印在控制台上。

Lua 函数主要有两种用途:

1.完成指定的任务,这种情况下函数作为调用语句使用;

2.计算并返回值,这种情况下函数作为赋值语句的表达式使用。

函数定义

Lua 编程语言函数定义格式如下:

optional_function_scope function function_name( argument1, argument2, argument3…, argumentn)

function_body

return result_params_comma_separated

end

解析

optional_function_scope: 该参数是可选的制定函数是全局函数还是局部函数,未设置该参数默认为全局函数,如果你需要设置函数为局部函数需要使用关键字 local。

function_name: 指定函数名称。

argument1, argument2, argument3…, argumentn: 函数参数,多个参数以逗号隔开,函数也可以不带参数。

function_body: 函数体,函数中需要执行的代码语句块。

result_params_comma_separated: 函数返回值,Lua语言函数可以返回多个值,每个值以逗号隔开。

实例

以下实例定义了函数 max(),参数为 num1, num2,用于比较两值的大小,并返回最大值:

–[[ 函数返回两个值的最大值 --]]

function max(num1, num2)

if (num1 > num2) then

result = num1;

else

result = num2;

end

return result;

end

– 调用函数

print("两值比较最大值为 ",max(10,4))

print("两值比较最大值为 ",max(5,6))

以上代码执行结果为:

两值比较最大值为 10

两值比较最大值为 6

Lua 中我们可以将函数作为参数传递给函数

如下实例:

myprint = function(param)

print(“这是打印函数 - ##”,param,“##”)

end

function add(num1,num2,functionPrint)

result = num1 + num2

– 调用传递的函数参数

functionPrint(result)

end

myprint(10)

– myprint 函数作为参数传递

add(2,5,myprint)

以上代码执行结果为:

这是打印函数 - ## 10 ##

这是打印函数 - ## 7 ##

多返回值

Lua函数可以返回多个结果值,比如string.find,其返回匹配串"开始和结束的下标"(如果不存在匹配串返回nil)。

s, e = string.find(“www.runoob.com”, “runoob”)

print(s, e)

5 10

Lua函数中,在return后列出要返回的值的列表即可返回多值

如:

function maximum (a)

local mi = 1 – 最大值索引

local m = a[mi] – 最大值

for i,val in ipairs(a) do

if val > m then

mi = i

m = val

end

end

return m, mi

end

print(maximum({8,10,23,12,5}))

以上代码执行结果为:

23 3

可变参数

Lua 函数可以接受可变数目的参数,和 C 语言类似,在函数参数列表中使用三点 … 表示函数有可变的参数。

function add(…)

local s = 0

for i, v in ipairs{…} do --> {…} 表示一个由所有变长参数构成的数组

s = s + v

end

return s

end

print(add(3,4,5,6,7)) —>25

我们可以将可变参数赋值给一个变量。

例如,我们计算几个数的平均值:

function average(…)

result = 0

local arg={…} --> arg 为一个表,局部变量

for i,v in ipairs(arg) do

result = result + v

end

print(“总共传入 " … #arg … " 个数”)

return result/#arg

end

print(“平均值为”,average(10,5,3,4,5,6))

以上代码执行结果为:

总共传入 6 个数

平均值为 5.5

我们也可以通过 select(“#”,…) 来获取可变参数的数量:

function average(…)

result = 0

local arg={…}

for i,v in ipairs(arg) do

result = result + v

end

print(“总共传入 " … select(”#“,…) … " 个数”)

return result/select(“#”,…)

end

print(“平均值为”,average(10,5,3,4,5,6))

以上代码执行结果为:

总共传入 6 个数

平均值为 5.5

上述的案例中涉及到”ipairs“和”pairs“的区别:

可查看此文章:lua 中ipairs和pairs的区别

有时候我们可能需要几个固定参数加上可变参数,固定参数必须放在变长参数之前:

function fwrite(fmt, …) —> 固定的参数fmt

return io.write(string.format(fmt, …))

end

fwrite(“iloveu\n”) —>fmt = “iloveu”, 没有变长参数。

fwrite(“%d%d\n”, 1, 2) —>fmt = “%d%d”, 变长参数为 1 和 2

输出结果为:

iloveu

12

通常在遍历变长参数的时候只需要使用 {…},然而变长参数可能会包含一些 nil,那么就可以用 select 函数来访问变长参数了:select(‘#’, …) 或者 select(n, …)

select(‘#’, …) 返回可变参数的长度。 select(n, …) 用于返回从起点 n 开始到结束位置的所有参数列表。

调用 select 时,必须传入一个固定实参 selector(选择开关) 和一系列变长参数。如果 selector 为数字 n,那么 select 返回参数列表中从索引 n 开始到结束位置的所有参数列表,否则只能为字符串 #,这样 select 返回变长参数的总数。

function f(…)

a = select(3,…) -->从第三个位置开始,变量 a 对应右边变量列表的第一个参数

print (a)

print (select(3,…)) -->打印所有列表参数

end

f(0,1,2,3,4,5)

输出结果为:

2

2 3 4 5

实例

do

function foo(…)

for i = 1, select(‘#’, …) do -->获取参数总数

local arg = select(i, …); -->读取参数,arg 对应的是右边变量列表的第一个参数

print(“arg”, arg);

end

end

foo(1, 2, 3, 4);

end

输出结果为:

arg 1

arg 2

arg 3

arg 4

九、运算符


运算符是一个特殊的符号,用于告诉解释器执行特定的数学或逻辑运算。Lua提供了以下几种运算符类型:

算术运算符 关系运算符 逻辑运算符 其他运算符

算术运算符

下表列出了 Lua 语言中的常用算术运算符,设定 A 的值为10,B 的值为 20:

在这里插入图片描述

实例

a = 21

b = 10

c = a + b

print("Line 1 - c 的值为 ", c )

c = a - b

print("Line 2 - c 的值为 ", c )

c = a * b

print("Line 3 - c 的值为 ", c )

c = a / b

print("Line 4 - c 的值为 ", c )

c = a % b

print("Line 5 - c 的值为 ", c )

c = a^2

print("Line 6 - c 的值为 ", c )

c = -a

print("Line 7 - c 的值为 ", c )

以上程序执行结果为:

Line 1 - c 的值为 31

Line 2 - c 的值为 11

Line 3 - c 的值为 210

Line 4 - c 的值为 2.1

Line 5 - c 的值为 1

Line 6 - c 的值为 441

Line 7 - c 的值为 -21

关系运算符

下表列出了 Lua 语言中的常用关系运算符,设定 A 的值为10,B 的值为 20:

在这里插入图片描述

实例

a = 21

b = 10

if( a == b )

then

print(“Line 1 - a 等于 b” )

else

print(“Line 1 - a 不等于 b” )

end

if( a ~= b )

then

print(“Line 2 - a 不等于 b” )

else

print(“Line 2 - a 等于 b” )

end

if ( a < b )

then

print(“Line 3 - a 小于 b” )

else

print(“Line 3 - a 大于等于 b” )

end

if ( a > b )

then

print(“Line 4 - a 大于 b” )

else

print(“Line 5 - a 小于等于 b” )

end

– 修改 a 和 b 的值

a = 5

b = 20

if ( a <= b )

then

print(“Line 5 - a 小于等于 b” )

end

if ( b >= a )

then

print(“Line 6 - b 大于等于 a” )

end

以上程序执行结果为:

Line 1 - a 不等于 b

Line 2 - a 不等于 b

Line 3 - a 大于等于 b

Line 4 - a 大于 b

Line 5 - a 小于等于 b

Line 6 - b 大于等于 a

逻辑运算符

下表列出了 Lua 语言中的常用逻辑运算符,设定 A 的值为 true,B 的值为 false:

在这里插入图片描述

实例

a = true

b = true

if ( a and b )

then

print(“a and b - 条件为 true” )

end

if ( a or b )

then

print(“a or b - 条件为 true” )

end

print(“---------分割线---------” )

– 修改 a 和 b 的值

a = false

b = true

if ( a and b )

then

print(“a and b - 条件为 true” )

else

print(“a and b - 条件为 false” )

end

if ( not( a and b) )

then

print(“not( a and b) - 条件为 true” )

else

print(“not( a and b) - 条件为 false” )

end

以上程序执行结果为:

a and b - 条件为 true

a or b - 条件为 true

---------分割线---------

a and b - 条件为 false

not( a and b) - 条件为 true

其他运算符

下表列出了 Lua 语言中的连接运算符与计算表或字符串长度的运算符:

在这里插入图片描述

实例

a = "Hello "

b = “World”

print("连接字符串 a 和 b ", a…b )

print("b 字符串长度 ",#b )

print("字符串 Test 长度 ",#“Test” )

以上程序执行结果为:

连接字符串 a 和 b Hello World

b 字符串长度 5

字符串 Test 长度 4

运算符优先级

从高到低的顺序:

^

not - (unary)

  •  /       %
    
  •  -
    

< > <= >= ~= ==

and

or

除了 ^ 和 … 外所有的二元运算符都是左连接的。

a+i < b/2+1 <–> (a+i) < ((b/2)+1)

5+x^2*8 <–> 5+((x^2)*8)

a < y and y <= z <–> (a < y) and (y <= z)

-x^2 <–> -(x^2)

xyz <–> x(yz)

实例

a = 20

b = 10

c = 15

d = 5

e = (a + b) * c / d;-- ( 30 * 15 ) / 5

print(“(a + b) * c / d 运算值为 :”,e )

e = ((a + b) * c) / d; – (30 * 15 ) / 5

print(“((a + b) * c) / d 运算值为 :”,e )

e = (a + b) * (c / d);-- (30) * (15/5)

print(“(a + b) * (c / d) 运算值为 :”,e )

e = a + (b * c) / d; – 20 + (150/5)

print(“a + (b * c) / d 运算值为 :”,e )

以上程序执行结果为:

(a + b) * c / d 运算值为 : 90.0

((a + b) * c) / d 运算值为 : 90.0

(a + b) * (c / d) 运算值为 : 90.0

a + (b * c) / d 运算值为 : 50.0

十、字符串


字符串或串(String)是由数字、字母、下划线组成的一串字符。

Lua 语言中字符串可以使用以下三种方式来表示:

单引号间的一串字符。

双引号间的一串字符。

[[ 与 ]] 间的一串字符。

实例

string1 = “Lua”

print(““字符串 1 是””,string1)

string2 = ‘baidu.com’

print(“字符串 2 是”,string2)

string3 = [[“Lua 教程”]]

print(“字符串 3 是”,string3)

转义字符用于表示不能直接显示的字符,比如后退键,回车键,等。如在字符串转换双引号可以使用 “”"。

所有的转义字符和所对应的意义:

在这里插入图片描述

字符串操作

string.upper(argument):

字符串全部转为大写字母。

string.lower(argument):

字符串全部转为小写字母。

string.gsub(mainString,findString,replaceString,num)

在字符串中替换。

mainString 为要操作的字符串, findString 为被替换的字符,replaceString 要替换的字符,num 替换次数(可以忽略,则全部替换),如:

string.gsub(“aaaa”,“a”,“z”,3);

zzza 3

string.find (str, substr, [init, [end]])

在一个指定的目标字符串 str 中搜索指定的内容 substr,如果找到了一个匹配的子串,就会返回这个子串的起始索引和结束索引,不存在则返回 nil。

以下实例查找字符串 “Lua” 的起始索引和结束索引位置:

string.find(“Hello Lua user”, “Lua”, 1)

7 9

string.reverse(arg)

字符串反转

string.reverse(“Lua”)

auL

string.format(…)

返回一个类似printf的格式化字符串

string.format(“the value is:%d”,4)

the value is:4

string.char(arg) 和 string.byte(arg[,int])

char 将整型数字转成字符并连接, byte 转换字符为整数值(可以指定某个字符,默认第一个字符)。

string.char(97,98,99,100)

abcd

string.byte(“ABCD”,4)

68

string.byte(“ABCD”)

65

string.len(arg)

计算字符串长度。

string.len(“abc”)

3

string.rep(string, n)

返回字符串string的n个拷贝

string.rep(“abcd”,2)

abcdabcd

链接两个字符串

print(“www.baidu.”…“com”)

www.baidu.com

string.gmatch(str, pattern)

回一个迭代器函数,每一次调用这个函数,返回一个在字符串 str 找到的下一个符合 pattern 描述的子串。如果参数 pattern 描述的字符串没有找到,迭代函数返回nil。

for word in string.gmatch(“Hello Lua user”, “%a+”) do print(word) end

Hello

Lua

user

string.match(str, pattern, init)

string.match()只寻找源字串str中的第一个配对. 参数init可选, 指定搜寻过程的起点, 默认为1。

在成功配对时, 函数将返回配对表达式中的所有捕获结果; 如果没有设置捕获标记, 则返回整个配对字符串. 当没有成功的配对时, 返回nil。

= string.match(“I have 2 questions for you.”, “%d+ %a+”)

2 questions

= string.format(“%d, %q”, string.match(“I have 2 questions for you.”, “(%d+) (%a+)”))

2, “questions”

字符串截取

字符串截取使用 sub() 方法。

string.sub() 用于截取字符串,原型为:

string.sub(s, i [, j])

参数说明:

s:要截取的字符串。

i:截取开始位置。

j:截取结束位置,默认为 -1,最后一个字符。

实例

– 字符串

local sourcestr = “prefix–runoobgoogletaobao–suffix”

print(“\n原始字符串”, string.format(“%q”, sourcestr))

– 截取部分,第1个到第15个

local first_sub = string.sub(sourcestr, 4, 15)

print(“\n第一次截取”, string.format(“%q”, first_sub))

– 取字符串前缀,第1个到第8个

local second_sub = string.sub(sourcestr, 1, 8)

print(“\n第二次截取”, string.format(“%q”, second_sub))

– 截取最后10个

local third_sub = string.sub(sourcestr, -10)

print(“\n第三次截取”, string.format(“%q”, third_sub))

– 索引越界,输出原始字符串

local fourth_sub = string.sub(sourcestr, -100)

print(“\n第四次截取”, string.format(“%q”, fourth_sub))

以上代码执行结果为:

原始字符串 “prefix–runoobgoogletaobao–suffix”

第一次截取 “fix–runoobg”

第二次截取 “prefix–”

第三次截取 “ao–suffix”

第四次截取 “prefix–runoobgoogletaobao–suffix”

字符串大小写转换

以下实例演示了如何对字符串大小写进行转换:

实例

string1 = “Lua”;

print(string.upper(string1))

print(string.lower(string1))

以上代码执行结果为:

LUA

lua

字符串查找与反转

以下实例演示了如何对字符串进行查找与反转操作:

实例

string = “Lua Tutorial”

– 查找字符串

print(string.find(string,“Tutorial”))

reversedString = string.reverse(string)

print(“新字符串为”,reversedString)

以上代码执行结果为:

5 12

新字符串为 lairotuT auL

字符串格式化

Lua 提供了 string.format() 函数来生成具有特定格式的字符串, 函数的第一个参数是格式 , 之后是对应格式中每个代号的各种数据。

由于格式字符串的存在, 使得产生的长字符串可读性大大提高了。这个函数的格式很像 C 语言中的 printf()。

以下实例演示了如何对字符串进行格式化操作:

格式字符串可能包含以下的转义码:

%c - 接受一个数字, 并将其转化为ASCII码表中对应的字符

%d, %i - 接受一个数字并将其转化为有符号的整数格式

%o - 接受一个数字并将其转化为八进制数格式

%u - 接受一个数字并将其转化为无符号整数格式

%x - 接受一个数字并将其转化为十六进制数格式, 使用小写字母

%X - 接受一个数字并将其转化为十六进制数格式, 使用大写字母

%e - 接受一个数字并将其转化为科学记数法格式, 使用小写字母e

%E - 接受一个数字并将其转化为科学记数法格式, 使用大写字母E

%f - 接受一个数字并将其转化为浮点数格式

%g(%G) - 接受一个数字并将其转化为%e(%E, 对应%G)及%f中较短的一种格式

%q - 接受一个字符串并将其转化为可安全被Lua编译器读入的格式

%s - 接受一个字符串并按照给定的参数格式化该字符串

为进一步细化格式, 可以在%号后添加参数. 参数将以如下的顺序读入:

(1) 符号: 一个+号表示其后的数字转义符将让正数显示正号. 默认情况下只有负数显示符号.

(2) 占位符: 一个0, 在后面指定了字串宽度时占位用. 不填时的默认占位符是空格.

(3) 对齐标识: 在指定了字串宽度时, 默认为右对齐, 增加-号可以改为左对齐.

(4) 宽度数值

(5) 小数位数/字串裁切: 在宽度数值后增加的小数部分n,

若后接f(浮点数转义符, 如%6.3f)则设定该浮点数的小数只保留n位,

若后接s(字符串转义符, 如%5.3s)则设定该字符串只显示前n位.

实例

string1 = “Lua”

string2 = “Tutorial”

number1 = 10

number2 = 20

– 基本字符串格式化

print(string.format(“基本格式化 %s %s”,string1,string2))

– 日期格式化

date = 2; month = 1; year = 2014

print(string.format(“日期格式化 %02d/%02d/%03d”, date, month, year))

– 十进制格式化

print(string.format(“%.4f”,1/3))

以上代码执行结果为:

基本格式化 Lua Tutorial

日期格式化 02/01/2014

0.3333

实例

string.format(“%c”, 83) – 输出S

string.format(“%+d”, 17.0) – 输出+17

string.format(“%05d”, 17) – 输出00017

string.format(“%o”, 17) – 输出21

string.format(“%u”, 3.14) – 输出3

string.format(“%x”, 13) – 输出d

string.format(“%X”, 13) – 输出D

string.format(“%e”, 1000) – 输出1.000000e+03

string.format(“%E”, 1000) – 输出1.000000E+03

string.format(“%6.3f”, 13) – 输出13.000

string.format(“%q”, “One\nTwo”) – 输出"One\

–   Two"

string.format(“%s”, “monkey”) – 输出monkey

string.format(“%10s”, “monkey”) – 输出 monkey

string.format(“%5.3s”, “monkey”) – 输出 mon

十一、 数组


数组,就是相同数据类型的元素按一定顺序排列的集合,可以是一维数组和多维数组。

Lua 数组的索引键值可以使用整数表示,数组的大小不是固定的。

一维数组

一维数组是最简单的数组,其逻辑结构是线性表。一维数组可以用for循环出数组中的元素,如下实例:

实例

array = {“Lua”, “Tutorial”}

for i= 0, 2 do

print(array[i])

end

以上代码执行输出结果为:

nil

Lua

Tutorial

正如你所看到的,我们可以使用整数索引来访问数组元素,如果知道的索引没有值则返回nil。

在 Lua 索引值是以 1 为起始,但你也可以指定 0 开始。

除此外我们还可以以负数为数组索引值:

实例

array = {}

for i= -2, 2 do

array[i] = i *2

end

for i = -2,2 do

print(array[i])

end

以上代码执行输出结果为:

-4

-2

0

2

4

多维数组

多维数组即数组中包含数组或一维数组的索引键对应一个数组。

以下是一个三行三列的阵列多维数组:

实例

– 初始化数组

array = {}

for i=1,3 do

array[i] = {}

for j=1,3 do

array[i][j] = i*j

end

end

– 访问数组

for i=1,3 do

for j=1,3 do

print(array[i][j])

end

end

以上代码执行输出结果为:

1

2

3

2

4

6

3

6

9

不同索引键的三行三列阵列多维数组:

实例

– 初始化数组

array = {}

maxRows = 3

maxColumns = 3

for row=1,maxRows do

for col=1,maxColumns do

array[rowmaxColumns +col] = rowcol

end

end

– 访问数组

for row=1,maxRows do

for col=1,maxColumns do

print(array[row*maxColumns +col])

end

end

以上代码执行输出结果为:

1

2

3

2

4

6

3

6

9

正如你所看到的,以上的实例中,数组设定了指定的索引值,这样可以避免出现 nil 值,有利于节省内存空间。

十二、迭代器


迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址。

在 Lua 中迭代器是一种支持指针类型的结构,它可以遍历集合的每一个元素。

泛型 for 迭代器

泛型 for 在自己内部保存迭代函数,实际上它保存三个值:迭代函数、状态常量、控制变量。

泛型 for 迭代器提供了集合的 key/value 对,语法格式如下:

for k, v in pairs(t) do

print(k, v)

end

上面代码中,k, v为变量列表;pairs(t)为表达式列表。

查看以下实例:

实例

array = {“Google”, “Runoob”}

for key,value in ipairs(array)

do

print(key, value)

end

以上代码执行输出结果为:

1 Google

2 Runoob

以上实例中我们使用了 Lua 默认提供的迭代函数 ipairs。

下面我们看看泛型 for 的执行过程:

首先,初始化,计算 in 后面表达式的值,表达式应该返回泛型 for 需要的三个值:迭代函数、状态常量、控制变量;与多值赋值一样,如果表达式返回的结果个数不足三个会自动用 nil 补足,多出部分会被忽略。

第二,将状态常量和控制变量作为参数调用迭代函数(注意:对于 for 结构来说,状态常量没有用处,仅仅在初始化时获取他的值并传递给迭代函数)。

第三,将迭代函数返回的值赋给变量列表。

第四,如果返回的第一个值为nil循环结束,否则执行循环体。

第五,回到第二步再次调用迭代函数

在Lua中我们常常使用函数来描述迭代器,每次调用该函数就返回集合的下一个元素。Lua 的迭代器包含以下两种类型:

无状态的迭代器 多状态的迭代器

无状态的迭代器

无状态的迭代器是指不保留任何状态的迭代器,因此在循环中我们可以利用无状态迭代器避免创建闭包花费额外的代价。

每一次迭代,迭代函数都是用两个变量(状态常量和控制变量)的值作为参数被调用,一个无状态的迭代器只利用这两个值可以获取下一个元素。

这种无状态迭代器的典型的简单的例子是 ipairs,它遍历数组的每一个元素,元素的索引需要是数值。

以下实例我们使用了一个简单的函数来实现迭代器,实现 数字 n 的平方:

实例

function square(iteratorMaxCount,currentNumber)

if currentNumber<iteratorMaxCount

then

currentNumber = currentNumber+1

return currentNumber, currentNumber*currentNumber

end

end

for i,n in square,3,0

do

print(i,n)

end

以上实例输出结果为:

1 1

2 4

3 9

迭代的状态包括被遍历的表(循环过程中不会改变的状态常量)和当前的索引下标(控制变量),ipairs 和迭代函数都很简单,我们在 Lua 中可以这样实现:

实例

function iter (a, i)

i = i + 1

local v = a[i]

if v then

return i, v

end

end

function ipairs (a)

return iter, a, 0

end

当 Lua 调用 ipairs(a) 开始循环时,他获取三个值:迭代函数 iter、状态常量 a、控制变量初始值 0;然后 Lua 调用 iter(a,0) 返回 1, a[1](除非 a[1]=nil);第二次迭代调用 iter(a,1) 返回 2, a[2]……直到第一个 nil 元素。

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

多状态的迭代器

很多情况下,迭代器需要保存多个状态信息而不是简单的状态常量和控制变量,最简单的方法是使用闭包,还有一种方法就是将所有的状态信息封装到 table 内,将 table 作为迭代器的状态常量,因为这种情况下可以将所有的信息存放在 table 内,所以迭代函数通常不需要第二个参数。

以下实例我们创建了自己的迭代器:

实例

array = {“Google”, “sougo”}

function elementIterator (collection)

local index = 0

local count = #collection

– 闭包函数

return function ()

index = index + 1

if index <= count

then

– 返回迭代器的当前元素

return collection[index]

end

end

end

for element in elementIterator(array)

do

print(element)

end

以上实例输出结果为:

Google

sougo

以上实例中我们可以看到,elementIterator 内使用了闭包函数,实现计算集合大小并输出各个元素。

十三、table(表)


table 是 Lua 的一种数据结构用来帮助我们创建不同的数据类型,如:数组、字典等。

Lua table 使用关联型数组,你可以用任意类型的值来作数组的索引,但这个值不能是 nil。

Lua table 是不固定大小的,你可以根据自己需要进行扩容。

Lua也是通过table来解决模块(module)、包(package)和对象(Object)的。 例如string.format表示使用"format"来索引table string。

table(表)的构造

构造器是创建和初始化表的表达式。表是Lua特有的功能强大的东西。最简单的构造函数是{},用来创建一个空表。可以直接初始化数组:

– 初始化表

mytable = {}

– 指定值

mytable[1]= “Lua”

– 移除引用

mytable = nil

– lua 垃圾回收会释放内存

当我们为 table a 并设置元素,然后将 a 赋值给 b,则 a 与 b 都指向同一个内存。如果 a 设置为 nil ,则 b 同样能访问 table 的元素。如果没有指定的变量指向a,Lua的垃圾回收机制会清理相对应的内存。

以下实例演示了以上的描述情况:

实例

– 简单的 table

mytable = {}

print("mytable 的类型是 ",type(mytable))

mytable[1]= “Lua”

mytable[“wow”] = “修改前”

print("mytable 索引为 1 的元素是 ", mytable[1])

print("mytable 索引为 wow 的元素是 ", mytable[“wow”])

– alternatetable和mytable的是指同一个 table

alternatetable = mytable

print("alternatetable 索引为 1 的元素是 ", alternatetable[1])

print("mytable 索引为 wow 的元素是 ", alternatetable[“wow”])

alternatetable[“wow”] = “修改后”

print("mytable 索引为 wow 的元素是 ", mytable[“wow”])

– 释放变量

alternatetable = nil

print("alternatetable 是 ", alternatetable)

– mytable 仍然可以访问

print("mytable 索引为 wow 的元素是 ", mytable[“wow”])

mytable = nil

print("mytable 是 ", mytable)

以上代码执行结果为:

mytable 的类型是 table

mytable 索引为 1 的元素是 Lua

mytable 索引为 wow 的元素是 修改前

alternatetable 索引为 1 的元素是 Lua

mytable 索引为 wow 的元素是 修改前

mytable 索引为 wow 的元素是 修改后

alternatetable 是 nil

mytable 索引为 wow 的元素是 修改后

mytable 是 nil

Table 操作

以下列出了 Table 操作常用的方法:

在这里插入图片描述

Table 连接

我们可以使用 concat() 输出一个列表中元素连接成的字符串:

实例

fruits = {“banana”,“orange”,“apple”}

– 返回 table 连接后的字符串

print("连接后的字符串 ",table.concat(fruits))

– 指定连接字符

print("连接后的字符串 “,table.concat(fruits,”, "))

– 指定索引来连接 table

print("连接后的字符串 “,table.concat(fruits,”, ", 2,3))

执行以上代码输出结果为:

连接后的字符串 bananaorangeapple

连接后的字符串 banana, orange, apple

连接后的字符串 orange, apple

插入和移除

以下实例演示了 table 的插入和移除操作:

实例

fruits = {“banana”,“orange”,“apple”}

– 在末尾插入

table.insert(fruits,“mango”)

print("索引为 4 的元素为 ",fruits[4])

– 在索引为 2 的键处插入

table.insert(fruits,2,“grapes”)

print("索引为 2 的元素为 ",fruits[2])

print("最后一个元素为 ",fruits[5])

table.remove(fruits)

print("移除后最后一个元素为 ",fruits[5])

执行以上代码输出结果为:

索引为 4 的元素为 mango

索引为 2 的元素为 grapes

最后一个元素为 mango

移除后最后一个元素为 nil

一线互联网大厂Java核心面试题库

image

正逢面试跳槽季,给大家整理了大厂问到的一些面试真题,由于文章长度限制,只给大家展示了部分题目,更多Java基础、异常、集合、并发编程、JVM、Spring全家桶、MyBatis、Redis、数据库、中间件MQ、Dubbo、Linux、Tomcat、ZooKeeper、Netty等等已整理上传,感兴趣的朋友可以看看支持一波!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

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

ble = {}

print("mytable 的类型是 ",type(mytable))

mytable[1]= “Lua”

mytable[“wow”] = “修改前”

print("mytable 索引为 1 的元素是 ", mytable[1])

print("mytable 索引为 wow 的元素是 ", mytable[“wow”])

– alternatetable和mytable的是指同一个 table

alternatetable = mytable

print("alternatetable 索引为 1 的元素是 ", alternatetable[1])

print("mytable 索引为 wow 的元素是 ", alternatetable[“wow”])

alternatetable[“wow”] = “修改后”

print("mytable 索引为 wow 的元素是 ", mytable[“wow”])

– 释放变量

alternatetable = nil

print("alternatetable 是 ", alternatetable)

– mytable 仍然可以访问

print("mytable 索引为 wow 的元素是 ", mytable[“wow”])

mytable = nil

print("mytable 是 ", mytable)

以上代码执行结果为:

mytable 的类型是 table

mytable 索引为 1 的元素是 Lua

mytable 索引为 wow 的元素是 修改前

alternatetable 索引为 1 的元素是 Lua

mytable 索引为 wow 的元素是 修改前

mytable 索引为 wow 的元素是 修改后

alternatetable 是 nil

mytable 索引为 wow 的元素是 修改后

mytable 是 nil

Table 操作

以下列出了 Table 操作常用的方法:

在这里插入图片描述

Table 连接

我们可以使用 concat() 输出一个列表中元素连接成的字符串:

实例

fruits = {“banana”,“orange”,“apple”}

– 返回 table 连接后的字符串

print("连接后的字符串 ",table.concat(fruits))

– 指定连接字符

print("连接后的字符串 “,table.concat(fruits,”, "))

– 指定索引来连接 table

print("连接后的字符串 “,table.concat(fruits,”, ", 2,3))

执行以上代码输出结果为:

连接后的字符串 bananaorangeapple

连接后的字符串 banana, orange, apple

连接后的字符串 orange, apple

插入和移除

以下实例演示了 table 的插入和移除操作:

实例

fruits = {“banana”,“orange”,“apple”}

– 在末尾插入

table.insert(fruits,“mango”)

print("索引为 4 的元素为 ",fruits[4])

– 在索引为 2 的键处插入

table.insert(fruits,2,“grapes”)

print("索引为 2 的元素为 ",fruits[2])

print("最后一个元素为 ",fruits[5])

table.remove(fruits)

print("移除后最后一个元素为 ",fruits[5])

执行以上代码输出结果为:

索引为 4 的元素为 mango

索引为 2 的元素为 grapes

最后一个元素为 mango

移除后最后一个元素为 nil

一线互联网大厂Java核心面试题库

[外链图片转存中…(img-kD4pfEgj-1715407808374)]

正逢面试跳槽季,给大家整理了大厂问到的一些面试真题,由于文章长度限制,只给大家展示了部分题目,更多Java基础、异常、集合、并发编程、JVM、Spring全家桶、MyBatis、Redis、数据库、中间件MQ、Dubbo、Linux、Tomcat、ZooKeeper、Netty等等已整理上传,感兴趣的朋友可以看看支持一波!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值