Step By Step(Lua表达式和语句)
Step By Step(Lua表达式和语句)
一、表达式:
1. 算术操作符:
Lua支持常规算术操作符有:二元的“+”、“-”、“*”、“/”、“^”(指数)、“%”(取模),一元的“-”(负号)。所有这些操作符都可用于实数。然而需要特别说明的是取模操作符(%),Lua中对该操作符的定义为:
a % b == a - floor(a / b) * b
由此可以推演出x % 1的结果为x的小数部分,而x - x % 1的结果则为x的整数部分。类似的,x - x % 0.01则是x精确到小数点后两位的结果。
2. 关系操作符:
Lua支持的关系操作符有:>、<、>=、<=、==、~=,所有这些操作符的结果均为true或false。
操作符==用于相等性测试,操作符~=用于不等性测试。这两个操作符可以应用于任意两个值。如果两个值的类型不同,Lua就认为他们不等。nil值与其自身相等。对于table、userdata和函数,Lua是通过引用进行比较的。也就是说,只有当他们引用同一个对象时,才视为相等。如:
1 a = {}
2 a.x = 1
3 a.y = 0
4 b = {}
5 b.x = 1
6 b.y = 1
7 c = a
其结果是a == c,但a ~= b。
对于字符串的比较,Lua是按照字符次序比较的。
3. 逻辑操作符:
Lua支持的逻辑操作符有:and、or和not。与条件控制语句一样,所有的逻辑操作符都将false和nil视为假,其他的结果均为真。和其他大多数语言一样,Lua中的and和or都使用“短路原则”。在Lua中有一种惯用写法"x = x or v",它等价于:if not x then x = v end。这里还有一种基于“短路原则”的惯用写法,如:
max = (x > y) and x or y
这等价于C语言中max = (x > y) ? x : y。由于x和y均为数值,因此它们的结果将始终为true。
4. 字符串连接:
前一篇Blog已经提到了字符串连接操作符(..),这里再给出一些简单的示例。
/> lua
> print("Hello " .. "World)
Hello World
> print(0 .. 1) --即使连接操作符的操作数为数值类型,在执行时Lua仍会将其自动转换为字符串。
01
5. table构造器:
构造器用于构建和初始化table的表达式。这是Lua特有的表达式,也是Lua中最有用、最通用的机制之一。其中最简单的构造器是空构造器{},用于创建空table。我们通过构造器还可以初始化数组,如:
1 days = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}
2 for i = 1,#days do
3 print(days[i])
4 end
5 --输出结果为
6 --Sunday
7 --Monday
8 --Tuesday
9 --Wednesday
10 --Thursday
11 --Friday
12 --Saturday
从输出结果可以看出,days在构造后会将自动初始化,其中days[1]被初始化为"Sunday",days[2]为"Monday",以此类推。
Lua中还提供了另外一种特殊的语法用于初始化记录风格的table。如:a = { x = 10, y = 20 },其等价于:a = {}; a.x = 10; a.y = 20
在实际编程时我们也可以将这两种初始化方式组合在一起使用,如:
polyline = {color = "blue", thickness = 2, npoints = 4,
{x = 0, y = 0},
{x = 10, y = 0},
{x = -10, y = 1},
{x = 0, y = 1} }
print(polyline["color"]);
print(polyline[2].x)
print(polyline[4].y)
--输出结果如下:
--blue
--10
--1
除了以上两种构造初始化方式之外,Lua还提供另外一种更为通用的方式,如:
1 opnames = { ["+"] = "add", ["-"] = "sub", ["*"] = "mul", ["/"] = "div"}
2 print(opnames["+"])
3 i = 20; s = "-"
4 a = { [i + 0] = s, [i + 1] = s .. s, [i + 2] = s..s..s }
5 print(a[22])
对于table的构造器,还有两个需要了解的语法规则,如:
a = { [1] = "red", [2] = "green", [3] = "blue", }
这里需要注意最后一个元素的后面仍然可以保留逗号(,),这一点类似于C语言中的枚举。
a = {x = 10, y = 45; "one", "two", "three" }
可以看到上面的声明中同时存在逗号(,)和分号(;)两种元素分隔符,这种写法在Lua中是允许的。我们通常会将分号(;)用于分隔不同初始化类型的元素,如上例中分号之前的初始化方式为记录初始化方式,而后面则是数组初始化方式。
二、语句:
1. 赋值语句:
Lua中的赋值语句和其它编程语言基本相同,唯一的差别是Lua支持“多重赋值”,如:a, b = 10, 2 * x,其等价于a = 10; b = 2 * x。然而需要说明的是,Lua在赋值之前需要先计算等号右边的表达式,在每一个表达式都得到结果之后再进行赋值。因此,我们可以这样写变量交互:x,y = y,x。如果等号右侧的表达式数量少于左侧变量的数量,Lua会将左侧多出的变量的值置为nil,如果相反,Lua将忽略右侧多出的表达式。
2. 局部变量与块:
Lua中的局部变量定义语法为:local i = 1,其中local关键字表示该变量为局部变量。和全局变量不同的是,局部变量的作用范围仅限于其所在的程序块。Lua中的程序可以为控制结构的执行体、函数执行体或者是一个程序块,如:
下面的x变量仅在while循环内有效。
1 while i <= x do
2 local x = i * 2
3 print(x)
4 i = i + 1
5 end
如果是在交互模式下,当执行local x = 0之后,该变量x所在的程序即以结束,后面的Lua语句将被视为新的程序块。如果想避免此类问题,我们可以显式的声明程序块,这样即便是在交互模式下,局部变量仍然能保持其块内有效性,如:
1 do
2 local a2 = 2 * a
3 local d = (b ^ 2 - 4 * a) ^ (1 / 2)
4 x1 = (-b + d) / a2
5 x2 = (-b - d) / a2
6 end --a2和d的作用域至此结束。
和其它编程语言一样,如果有可能尽量使用局部变量,以免造成全局环境的变量名污染。同时由于局部变量的有效期更短,这样垃圾收集器可以及时对其进行清理,从而得到更多的可用内存。
3. 控制结构:
Lua中提供的控制语句和其它大多数开发语言所提供的基本相同,因此这里仅仅是进行简单的列举。然后再给出差异部分的详细介绍。如:
1). if then else
if a < 0 then
b = 0
else
b = 1
end
2). if elseif else then
if a < 0 then
b = 0
elseif a == 0 then
b = 1
else
b = 2
end
3). while
local i= 1
while a[i] do
print(a[i])
i = i + 1
end
4). repeat
repeat
line = io.read()
until line ~= "" --直到until的条件为真时结束。
print(line)
5). for
for var = begin, end, step do --如果没有step变量,begin的缺省步长为1。
i = i + 1
end
需要说明的是,for循环开始处的三个变量begin、end和step,如果它们使表达式的返回值,那么该表达式将仅执行一次。再有就是不要在for的循环体内修改变量var的值,否则会导致不可预知的结果。
6). foreach
for i, v in ipairs(a) do --ipairs是Lua自带的系统函数,返回遍历数组的迭代器。
print(v)
end
for k in pairs(t) do --打印table t中的所有key。
print(k)
end
见如下示例代码:
1 days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }
2 revDays = {}
3 for k, v in ipairs(days) do
4 revDays[v] = k
5 end
6
7 for k in pairs(revDays) do
8 print(k .. " = " .. revDays[k])
9 end
10
11 --输出结果为:
12 --Saturday = 7
13 --Tuesday = 3
14 --Wednesday = 4
15 --Friday = 6
16 --Sunday = 1
17 --Thursday = 5
18 --Monday = 2
7). break
和C语言中的break语义完全相同,即跳出最内层循环。
Step By Step(Lua表达式和语句)的更多相关文章
- Step By Step(Lua编译执行与错误)
Step By Step(Lua编译执行与错误) 1. 编译: Lua中提供了dofile函数,它是一种内置的操作,用于运行Lua代码块.但实际上dofile只是一个辅助函数,loadfile才 ...
- Step By Step(Lua函数)
Step By Step(Lua函数) 一.函数: 在Lua中函数的调用方式和C语言基本相同,如:print("Hello World")和a = add(x, y).唯一的 ...
- Step By Step(Lua基础知识)
Step By Step(Lua基础知识) 一.基础知识: 1. 第一个程序和函数: 在目前这个学习阶段,运行Lua程序最好的方式就是通过Lua自带的解释器程序,如: /> l ...
- Step By Step(Lua元表与元方法)
Step By Step(Lua元表与元方法) Lua中提供的元表是用于帮助Lua数据变量完成某些非预定义功能的个性化行为,如两个table的相加.假设a和b都是table,通过元表可以定义如何计算表 ...
- Step By Step(Lua数据持久化)
Step By Step(Lua数据持久化) 1. 数据文件: 我们可以利用Lua中table的构造式来定义一种文件格式,即文件中的数据是table构造并初始化的代码,这种方式对于Lua程序而言 ...
- Step By Step(Lua迭代器和泛型for)
Step By Step(Lua迭代器和泛型for) 1. 迭代器与Closure: 在Lua中,迭代器通常为函数,每调用一次函数,即返回集合中的"下一个"元素.每个迭代器都 ...
- Step By Step(C调用Lua)
Step By Step(C调用Lua) 1. 基础: Lua的一项重要用途就是作为一种配置语言.现在从一个简单的示例开始吧. --这里是用Lua代码定义的窗口大小的配置信息 wid ...
- Step By Step(Lua系统库)
Step By Step(Lua系统库) Lua为了保证高度的可移植性,因此,它的标准库仅仅提供了非常少的功能,特别是和OS相关的库.但是Lua还提供了一些扩展库,比如Posix库等.对于文件操作而言 ...
- Step By Step(Lua输入输出库)
Step By Step(Lua输入输出库) I/O库为文件操作提供了两种不同的模型,简单模型和完整模型.简单模型假设一个当前输入文件和一个当前输出文件,他的I/O操作均作用于这些文件.完整模型则使用 ...
随机推荐
- .Net之Docker部署详细流程
开篇语 自己从头开始走一遍docker部署.net的流程,作为一种学习总结,以及后续会写一些在该基础之上的文章. 本次示例环境:vs2019.net5.docker.postman 创建项目 本次事例 ...
- Spring Security极简入门三部曲(上篇)
目录 Spring Security极简入门三部曲(上篇) 写在前面 为什么要用Spring Security 数据库设计 demo时刻 核心代码讲解 小结 Spring Security极简入门三部 ...
- pyqt5 菜单栏+信息提示框
前言 使用pyqt5 添加菜单栏 单击菜单栏 弹出信息框(MessageBox用法) 菜单栏 功能 Action是Qt中单独引入的一个对象,对应QAction类.Action表示一个独立的操作,是将界 ...
- CVE-2018-8174(双杀漏洞)复现
目录 CVE-2018-8174双杀漏洞复现一(不稳定) 下载payload MSF监听 CVE-2018-8174双杀漏洞复现二
- SqlServer 数据库配置远程桌面
1.是否开启远程桌面,1表示关闭,0表示开启 EXEC master..xp_regread 'HKEY_LOCAL_MACHINE','SYSTEM\CurrentControlSet\Contro ...
- 神经网络与机器学习 笔记—Rosenblatt感知器收敛算法C++实现
Rosenblatt感知器收敛算法C++实现 算法概述 自己用C++实现了下,测试的例子和模式用的都是双月分类模型,关于双月分类相关看之前的那个笔记: https://blog.csdn.net/u0 ...
- <JVM上篇:内存与垃圾回收篇>02-类加载子系统
笔记来源:尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机) 同步更新:https://gitee.com/vectorx/NOTE_JVM https://codechina.cs ...
- 视频格式mkv、mp4、avi、flv、mov、wmv、webm特点和区别
mkv是一种多媒体封装格式,这个封装格式可把多种不同编码的影像及 16 条或以上不同格式的音频和语言不同的字幕封装到一个 Matroska Media 档内. 它也是其中一种开放原始码的多媒体封装格式 ...
- Vue.js源码解析-从scripts脚本看vue构建
目录 1. scripts 脚本构建 1.1 dev 开发环境构建过程 1.1.1 配置文件代码 1.1.2 如何进行代码调试? 1.2 build 生产环境构建过程 1.2.1 scripts/bu ...
- babylin使用思路