02Lua入门

news/2024/12/2 6:55:34/

前言:

语言学起来其实相似点很多,简单整理的知识点

目录:

1.使用控制台
2.Lua基础
3.变量
4.运算符
5.控制结构


1.使用控制台
Lua脚本是包含一系列Lua命令的简单脚本(扩展名为.lua的文本文件)。Lua不关注格式,制表符,换行符或者其他让脚本文件更具可读性的转换符号(不过Lua还是需要命令之间的空格符号,用来区别变量和函数调用)
简单的Lua脚本:
for indx = 1,4 do
print("line:",indx )
end
也可以写成:for indx = 1,4 do print("line:",indx ) end
注:
格式化后的脚本更容易阅读,但不改变结果
可以把脚本放在本地文件夹通过dofile命令来在控制台执行脚本,参数是字符串,指定文件的名字和路径。使用dofile命令可以在命令行中运行脚本,如果脚本有什么错误的化,命令行会给出错误信息以便调试。
语法格式:
dofile<"c:\\file_name\\lua_scripts_name.lua">

2.Lua基础
优势:整合C++的模块来扩展自身的功能。

语言定义
不以数字为标识符开头(同C),避免下划线接大写字母(_NAME),因为这种格式是Lua自身保留的(保留字),如_Start。
Lua保留关键字
and    local    break    nil    do
not    else    or    elseif    repeat
end    return    false    then    for
true    function    until    if    while
in
变量,常量,函数名的格式和命名规则:
常用全大写和下划线(MY_NAME)
变量第一个字母小写(myVariable)
全局变量第一个字母用小写(gMyGlobal)
函数名第一个字母大写(function  MyFunction)
--单行注释
--[[
     statements    块注释
--]]
使用技巧:--[[ 或者 --]]  加一个 - 可以重新使用这段代码  ---[[   ---]]


3.变量
在Lua中,变量不需要在使用前声明,这个稍微有些争议。因为不需要声明,所以可以才任何地方引入需要的变量。由于不是显式声明,所以很难追踪变量(不造),或者在另一个函数中用了相同名字的变量而造成数据的混乱。因此,必须小心的使用变量,要保证变量是可追踪的。同样不需要指定变量类型,变量类型取决于给变量赋的值,灵活性较高。

变量赋值:
1.赋值改变
2.改变表域
多个变量同时赋值时赋值变量列表和值列表的各个元素用逗号分开,依次赋值。
a,b=1,2
遇到赋值语句Lua会先计算右边所有的值然后在执行赋值操作,所以我们可以这样进行交换变量的值。
x,y=y,x
当变量个数与值个数不一致时,Lua会以变量个数为基础,采取不足补nil,多的忽略。
例:
a,b,c=0,1   --->0,1,nil
a,b,c=0,1,2,3 --->0,1,2
多值赋值常用来交换变量,或将函数调用返回给变量。
例:
a, b = f()
f()返回两个值,第一个赋给a,第二个赋给b。
应该尽可能的使用局部变量,有两个好处:
1. 避免命名冲突。
2. 访问局部变量的速度比全局变量更快。

索引
对 table 的索引使用方括号 []。Lua 也提供了 . 操作。
t[i]
t.i                 -- 当索引为字符串类型时的一种简化写法
gettable_event(t,i) -- 采用索引访问本质上是一个类似这样的函数调用
例如:

> site = {}
> site["key"] = "www.w3cschool.cc"
> print(site["key"])
www.w3cschool.cc

> print(site.key)
www.w3cschool.cc


变量类型:
注:可以使用Type函数测试变量的类型。

3.1 nil
nil 表示没赋值的变量,实际上可以表示删除变量。
3.2Boolean
Boolean类型的变量只有两种值 :true和false.
3.3string
3.3.1用两个方括号也可以表示一块字符串

特殊字符串:
\a    响铃    \v    垂直指标
\b    退格    \\    反斜杠
\f    换页符    \"    双引号
\n    换行符    \'    单引号
\r    换行符    \[    左方括号
\t    制表符    \]    右方括号
\o    空字符    \ddd    八进制
\xhh    十六进制
3.3.2在对一个数字字符串进行操作时,Lua会将这个数字字符串转换成一个数字。
例子:
print(2+6)--8
print("2"+6)--8
print("2"+"6")--8
print("2+6")--2+6
print("abc"+6)--报错,字符串连接不是用+而是两点 ..
print("2"..6)--26
注:..(连接字符串)
       #(计算字符串长度,置于字符串前或者变量名前)
3.4Number

双精度浮点数,无整数类型
myNumber=7
myNumber=0.765
myNumber=7.65e8(7.65x10^8,765 000 000)
myNumber=7.65e-2(7.65x10^-2,0.0765)


3.5table

3.5.1实质是关联数组(associative arrays)索引为数字或字符串,初始索引为1.
3.5.2table的创建
3.5.2.1空表
local tab1={}
3.5.2.2初始表
local tab2={"apple","pear"}
注:table不会固定长度大小,有新数据添加时,table会自动增长,没有初始值都为nil.


3.6局部变量和全局变量
Lua变量默认是全局的,也就是说,变量的值在整个会话中是保持不变的,除非脚本改变了它。
当使用全局变量时,变量名前加一个g字母会更加明确,便于调试。
局部变量可以给设定一个初始值,也可以不用赋值。
语法:
local 变量名

变量的有效范围取决于声明变量的位置。


4.运算符

4.1算术运算符

+-*/%^-

4.2关系运算符
==
~=
>
<
>=
<=
注:如果使用关系运算符比较两个table,只有两个table是同一个对象的时候才能得到预期的结果,因为变量只是table对象的引用(像指针一样),不能直接比较存在于table中的值。
实例:
tableA={1,2,3}
tableB={1,2,3}
if tableA=tableB then
     print("相等")
else
     print("不相等")
end
-->不相等(结构不同)
tableA={1,2,3}
tableB=tableA
if tableA=tableB then
     print("相等")
else
     print("不相等")
end
-->相等(tableB指向了同样的对象tableA)

4.3逻辑运算符
and(比较两个参数时,第一个false则返回flase,否则返回第二个参数的值)
or
not
注:官方解释的是一坨屎,就和C一样理解就行。
4.4其他运算符
.. 连接字符串
#一元运算符,返回字符串或表的长度


4.5运算符的优先级
从高到低的顺序:
^
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)
x^y^z                <-->       x^(y^z)
实例
我们可以通过以下实例来更加透彻的了解 Lua 语言运算符的优先级:
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
注:除了^和..外所有二元运算符都是左连接的。

笔记:
1.在Lua中实现C/C++中的三目运算。
condition?  result1:result2
|
if  condition then
return result1
else
return result2
end

三目运算
熟悉 C/C++ 的老司机都知道三目运算 a ? b : c,这种写法替换简单的条件判断语句可以在不增加阅读难度的情况下,使代码尽量保持简洁。
int a, b, ret;
//if-else
if (a > b)
     ret = a;
else
     ret = b;

//三目运算符
ret = a > b ? a : b;
Lua 中的三目运算
Lua 原生的语义并没有实现三目运算,一般是通过逻辑运算符 and 和 or 来模拟三目运算符的。
Lua 中 and 和 or 都使用"短路求值(short_cur evaluation)",也就是说,它们只会在需要时才去评估第二个操作数。(《Lua程序设计》)
local a, b, ret;
ret = a > b and a or b
穷举所有可能性:
a > b 时:
a > b and a –> true
a or b –> a
a <= b时:
a > b and a –> false
a or b –> b
完美!
Lua 中的三目运算符陷阱
按照从特殊到一般的原则:
三目运算的一般形式a ? b : c
a = true,结果为b
a = false,结果为c
对应Lua中的a and b or c
b = true
a = true
a and b –> true
b or c –> b
a = false
a and b –> false
b or c –> c
b = false
a = true
a and b –> false
b or c –> c
a = false
a and b –> false
b or c –> c
可以看到当 b = false 时,Lua模拟的 a and b or c 始终返回 c 并不能还原三目运算符的原貌。
《Lua程序设计》也建议这种情况使用 if-else 来避免。
一般化的 a and b or c
那么有没有办法可以解决 b = false 失效的问题呢?
由此我联想到 C 语言有一道常规的考题:请使用宏定义写一个返回两个值中较小值的方法。
在校时第一次看到本题,第一反应如下:
#define MIN(A,B) A < B ? A : B
然而这种写法在很多嵌套的使用环境中都不能返回正确的结果。比如:2 * MIN(3, 4)展开为 2 * 3 < 4 ? 3 : 4 = 6 < 4 ? 3 : 4,结果为4。
更"工程师"的写法是:
#define MIN(A,B) ((A) < (B) ? (A) : (B))
还有好奇心的同学可以参考:宏定义的正确写法,三目运算的宏定义
从这个示例中,我就在想如何能保证 a and b or c 中 b 为真或者 b 不产生歧义呢?
and的运算优先级高于or,简单的改变运算顺序并没有用。
这时就想到了lua中万能的table,能不能把a,b,c都放到table中来改变b的存在呢?要注意{nil}也是一个为true的对象。
a,b,c都替换为table:{a} and {b} or {c}。
三目运算中a是条件,结果是b或者c。其实a并不需要放入table中,否则{a}就始终为true了,失去了条件的意义。而{b} or
{c}的结果也必然是一个table,该table只有一个元素。那么通过[1]即可访问。
综上所述,更一般化的Lua三目运算为:(a and {b} or {c})[1]


2.其他运算符 —— #
在获取表的长度时,根据的是表的最大索引的值:
tab1 = {"1","2"}
print("tab1长度"..#tab1)
tab2 = {key1="1","2"}
print("tab2长度"..#tab2)
tab3 = {}
tab3[1]="1"
tab3[2]="2"
tab3[4]="4"
print("tab3长度"..#tab3)
输出:
tab1长度2
tab2长度1
tab3长度4

3. 下标越过 1 位以上,长度还是为 2:
tab3={}
tab3[1]="1"
tab3[2]="2"
tab3[5]="5"
print("tab3的长度",#tab3)
输出:
tab3的长度    2


4.取长度操作符写作一元操作 #
table t 的长度被定义成一个整数下标 n 。 它满足 t[n] 不是 nil 而 t[n+1] 为 nil; 此外,如果 t[1] 为 nil ,n 就可能是零。 对于常规的数组,里面从 1 到 n 放着一些非空的值的时候, 它的长度就精确的为 n,即最后一个值的下标。 如果数组有一个“空洞” (就是说,nil 值被夹在非空值之间), 那么 #t 可能是指向任何一个是 nil 值的前一个位置的下标 (就是说,任何一个nil 值都有可能被当成数组的结束)。
tab4 = {}
tab4[1] = "1"
tab4[2] = nil
tab4[3] = "2"
tab4[4] = nil
print("tab4的长度", #tab4)

--tab4的长度    1

tab5 = {}
tab5[1] = "1"
tab5[2] = nil
tab5[3] = "2"
tab5[4] = "4"
print("tab5的长度", #tab5)

--tab5的长度    4

tab6 = {1, nil, 3}
print("tab6的长度", #tab6)

--tab6的长度    3

tab6 = {1, nil, 3, nil}
print("tab6的长度", #tab6)

--tab6的长度    1
5.控制结构
注:
控制结构的条件表达式结果可以是任何值,Lua认为false和nil为假,true和非nil为真。
要注意的是Lua中 0 为 true:
5.1if 语句
if 语句 由一个布尔表达式作为条件判断,其后紧跟其他语句组成。
Lua if 语句语法格式如下:

if(布尔表达式)
then
    --[ 在布尔表达式为 true 时执行的语句 --]
end

在布尔表达式为 true 时会if中的代码块会被执行,在布尔表达式为 false 时,紧跟在 if 语句 end 之后的代码会被执行。
Lua认为false和nil为假,true 和非nil为真。要注意的是Lua中 0 为 true。


5.2if...else 语句

if 语句 可以与 else 语句搭配使用, 在 if 条件表达式为 false 时执行 else 语句代码。
if...else 语句
Lua if 语句可以与 else 语句搭配使用, 在 if 条件表达式为 false 时执行 else 语句代码块。
Lua if...else 语句语法格式如下:
if(布尔表达式)
then
    --[ 布尔表达式为 true 时执行该语句块 --]
else
    --[ 布尔表达式为 false 时执行该语句块 --]
end

在布尔表达式为 true 时会if中的代码块会被执行,在布尔表达式为 false 时,else 的代码块会被执行。
Lua认为false和nil为假,true 和非nil为真。要注意的是Lua中 0 为 true。

if...elseif...else 语句
Lua if 语句可以与 elseif...else 语句搭配使用, 在 if 条件表达式为 false 时执行 elseif...else 语句代码块,用于检测多个条件语句。
Lua if...elseif...else 语句语法格式如下:
if( 布尔表达式 1)
then
    --[ 在布尔表达式 1 为 true 时执行该语句块 --]

elseif( 布尔表达式 2)
then
    --[ 在布尔表达式 2 为 true 时执行该语句块 --]

elseif( 布尔表达式 3)
then
    --[ 在布尔表达式 3 为 true 时执行该语句块 --]
else
    --[ 如果以上布尔表达式都不为 true 则执行该语句块 --]
end


5.3if 嵌套语句
你可以在if 或 else if中使用一个或多个 if 或 else if 语句 。

if...else 语句
Lua if 语句允许嵌套, 这就意味着你可以在一个 if 或 else if 语句中插入其他的 if 或 else if 语句。
Lua if 嵌套语句语法格式如下:

if( 布尔表达式 1)
then
    --[ 布尔表达式 1 为 true 时执行该语句块 --]
    if(布尔表达式 2)
    then
       --[ 布尔表达式 2 为 true 时执行该语句块 --]
    end
end
你可以用同样的方式嵌套 else if...else 语句。


注:Lua不支持case语句因此可以用elseif语句


5.4循环
Lua 语言提供了以下几种循环处理方式:

while 循环
在条件为 true 时,让程序重复地执行某些语句。执行语句前会先检查条件是否为 true。
for 循环
重复执行指定语句,重复次数可在 for 语句中控制。
repeat...until
重复执行循环,直到 指定的条件为真时为止
循环嵌套
可以在循环内嵌套一个或多个循环语句(while do ... end;for ... do ... end;repeat ... until;)


5.4.1while
注:
while和repeat 控制结构非常相似,它们都可以循环执行一段脚本直到满足某个条件。
Lua 编程语言中 while 循环语句在判断条件为 true 时会重复执行循环体语句。
语法
Lua 编程语言中 while 循环语法:
while(condition)
do
    statements
end


5.4.2repeat
repeat...until 循环的条件语句在当前循环结束后判断。
语法
Lua 编程语言中 repeat...until 循环语法格式:
repeat
    statements
until( condition )

5.4.3for
Lua 编程语言中 for 循环语句可以重复执行指定语句,重复次数可在 for 语句中控制。
Lua 编程语言中 for语句有两大类:
数值for循环
泛型for循环

5.4.3.1数值for循环

Lua 编程语言中数值for循环语法格式:
for var=exp1,exp2,exp3 do 
     <执行体> 
end
  
var从exp1变化到exp2,每次变化以exp3为步长递增var,并执行一次"执行体"。exp3是可选的,如果不指定,默认为1。

示例:
for i=10,1,-1 do
     print(i)
end
从10变到1,每次减1
结果:10,9,8,7,6,5,4,3,2,1


5.4.3.2泛型for循环

泛型for循环通过一个迭代器函数来遍历所有值,类似java中的foreach语句。
Lua 编程语言中泛型for循环语法格式:
--打印数组a的所有值 
for i,v in ipairs(a)
     do print(v)
end 
i是数组索引值,v是对应索引的数组元素值。ipairs是Lua提供的一个迭代器函数,用来迭代数组。

days ={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"} 
for i,v in ipairs(days) do 
print(v)
  end  

结果略(ipairs(为表达式列表),后面泛型for里有提到)
注:
1.循环次数只是在第一次执行时确定,因此就算用户更改了参数的值也不会影响最终的循环次数。
2.循环结构中的变量是局部变量,一旦循环结束就会被清除。如果想保存它们的值
,那么必须使用全局变量或者更高级的局部变量。
笔记:
1.
在lua中pairs与ipairs两个迭代器的用法相近,但有一点是不一样的:
pairs可以遍历表中所有的key,并且除了迭代器本身以及遍历表本身还可以返回nil;
但是ipairs则不能返回nil,只能返回数字0,如果遇到nil则退出。它只能遍历到表中出现的第一个不是整数的key
2.pairs遍历表中全部key,value
ipairs从下标为1开始遍历,然后下标累加1,如果某个下标元素不存在就终止遍历。这就导致如果下标不连续或者不是从1开始的表就会中断或者遍历不到元素。
3.
首先,ipairs 这个迭代器只能遍历所有数组下标的值,这是前提,也是和 pairs 的最根本区别,也就是说如果 ipairs 在迭代过程中是会直接跳过所有手动设定key值的变量。
特别注意一点,和其他多数语言不同的地方是,迭代的下标是从1开始的。
3.1
例如:
tab = {1,2,a= nil,"d"}
for i,v in ipairs(tab) do
     print(i,v)
end
输出结果为:
1  1
2  2
3  d
这里是直接跳过了a=nil这个变量
3.2
ipairs在迭代过程中如果遇到nil时会直接停止。
例如:
tab = {1,2,a= nil,nil,"d"}
for i,v in ipairs(tab) do
     print(i,v)
end
输出结果为:
1  1
2  2

4.
for 循环中,循环的索引 i 为外部索引,修改循环语句中的内部索引 i,不会影响循环次数:
for i=1,10 do
     i = 10
     print("one time,i:"..i)
end
仍然循环 10 次,只是 i 的值被修改了。


5.5嵌套循环

语法
Lua 编程语言中 for 循环嵌套语法格式:
for init,max/min value, increment
do
    for init,max/min value, increment
    do
       statements
    end
    statements
end
Lua 编程语言中 while 循环嵌套语法格式:
while(condition)
do
    while(condition)
    do
       statements
    end
    statements
end
Lua 编程语言中 repeat...until 循环嵌套语法格式:
repeat
    statements
    repeat
       statements
    until( condition )
until( condition )
除了以上同类型循环嵌套外,我们还可以使用不同的循环类型来嵌套,如 for 循环体中嵌套 while 循环。

实例
以下实例使用了for循环嵌套:
j =2
for i=2,10 do
    for j=2,(i/j) , 2 do
       if(not(i%j))
       then
          break
       end
       if(j > (i/j))then
          print("i 的值为:",i)
       end
    end
end
以上代码执行结果为:
i 的值为:    8
i 的值为:    9
i 的值为:    10


5.6循环控制语句
循环控制语句用于控制程序的流程, 以实现程序的各种结构方式。
Lua 支持以下循环控制语句:
break 语句
退出当前循环或语句,并开始脚本执行紧接着的语句。



5.7无限循环
在循环体中如果条件永远为 true 循环语句就会永远执行下去,以下以 while 循环为例:
while( true )
do
    print("循环将永远执行下去")
end

转载于:https://www.cnblogs.com/fenqinearl/p/9249049.html


http://www.ppmy.cn/news/614458.html

相关文章

php无表单上传文件,php – 来自表单的WP邮件附件,无文件管理器上传文件

从表单通过wp_mail函数我正在尝试发送带附件的电子邮件,而不将文件上传到文件管理器.我收到附件的电子邮件.但附件名称不正确,没有文件类型.请帮忙解决这个问题.这是HTML表单有我的PHP代码if (isset($_POST[Submit])) {$attachments $_FILES[Attached][tmp_name];$recipients …

目标跟踪算法

目标跟踪算法 一&#xff0e;互相关运算 给你一张我的正脸照&#xff08;没有经过美颜处理的&#xff09;&#xff0c;你该如何在人群中找到我呢&#xff1f;一种最直观的方案就是&#xff1a;“谁长得最像就是谁”。但是对于计算机来说&#xff0c;如何衡量“长得像”&#…

Spring Boot中的@RequestMapping注解,如何使用

Spring Boot中的RequestMapping注解 介绍 Spring Boot是一个流行的Java框架&#xff0c;它提供了许多方便的注解和工具&#xff0c;使得Web应用程序的开发变得更加容易。其中&#xff0c;RequestMapping注解是Spring Boot中最常用的注解之一&#xff0c;它可以帮助开发者定义…

JS继承的实现方式

原型链继承&#xff1a;//原型链继承&#xff1a;把父类的私有公有的属性和方法&#xff0c;都作为子类公有的属性&#xff1b;//核心&#xff1a;不是把父类私有公有的属性克隆一份一模一样的给子类的公有吧&#xff1b;他是通过__proto__建立和子类之间的原型链&#xff0c;当…

单目测距算法

单目测距算法 相似三角形 用相似三角形计算物体或者目标到相机的距离&#xff0c;将使用相似三角形来计算相机到一个已知的物体或者目标的距离。 假设有一个宽度为 W 的目标或者物体。然后将这个目标放在距离的相机为 D 的位置。用相机对物体进行拍照并且测量物体的像素宽度…

LeetCode-198. 打家劫舍

题目描述 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。 给定一个代表每个房屋存…

php 解决方案,php优化解决方案

php优化本帖最后由 xuzuning 于 2013-09-30 13:05:14 编辑//define server info begin$servername "192.168.1.182";$serverusername "whh";$serverpassword "whh";$database"whh";$usertable"user";$userfield"use…

FCN与U-Net语义分割算法

FCN与U-Net语义分割算法 图像语义分割(Semantic Segmentation)是图像处理和是机器视觉技术中关于图像理解的重要一环&#xff0c;也是 AI 领域中一个重要的分支。语义分割即是对图像中每一个像素点进行分类&#xff0c;确定每个点的类别&#xff08;如属于背景、人或车等&…