侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

Lua教程(三):表达式和语句

技术  /  管理员 发布于 5年前   376

一、表达式:

    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是通过引用进行比较的。也就是说,只有当他们引用同一个对象时,才视为相等。如:
复制代码 代码如下:
a = {}
a.x = 1
a.y = 0
b = {}
b.x = 1
b.y = 1
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。我们通过构造器还可以初始化数组,如:

复制代码 代码如下:
days = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}
for i = 1,#days do
    print(days[i])
end
--输出结果为
--Sunday
--Monday
--Tuesday
--Wednesday
--Thursday
--Friday
--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还提供另外一种更为通用的方式,如:
复制代码 代码如下:
opnames = { ["+"] = "add", ["-"] = "sub", ["*"] = "mul", ["/"] = "div"}
print(opnames["+"])
i = 20; s = "-"
a = { [i + 0] = s, [i + 1] = s .. s, [i + 2] = s..s..s }
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循环内有效。
复制代码 代码如下:
while i <= x do
    local x = i * 2
     print(x)
     i = i + 1
end

    如果是在交互模式下,当执行local x = 0之后,该变量x所在的程序即以结束,后面的Lua语句将被视为新的程序块。如果想避免此类问题,我们可以显式的声明程序块,这样即便是在交互模式下,局部变量仍然能保持其块内有效性,如:
复制代码 代码如下:
do
    local a2 = 2 * a
    local d = (b ^ 2 - 4 * a) ^ (1 / 2)
    x1 = (-b + d) / a2
    x2 = (-b - d) / a2
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
 
    见如下示例代码:
 复制代码 代码如下:
 days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }
revDays = {}
for k, v in ipairs(days) do
    revDays[v] = k
end

for k in pairs(revDays) do
    print(k .. " = " .. revDays[k])
end

--输出结果为:
--Saturday = 7
--Tuesday = 3
--Wednesday = 4
--Friday = 6
--Sunday = 1
--Thursday = 5
--Monday = 2
 

   7). break
    和C语言中的break语义完全相同,即跳出最内层循环。


  • 上一条:
    什么是Perl?编程语言Perl详细介绍
    下一条:
    html5指南-5.使用web storage存储键值对的数据
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 2024.07.09日OpenAI将终止对中国等国家和地区API服务(0个评论)
    • 2024/6/9最新免费公益节点SSR/V2ray/Shadowrocket/Clash节点分享|科学上网|免费梯子(1个评论)
    • 国外服务器实现api.openai.com反代nginx配置(0个评论)
    • 2024/4/28最新免费公益节点SSR/V2ray/Shadowrocket/Clash节点分享|科学上网|免费梯子(1个评论)
    • 近期文章
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-07
    • 2017-08
    • 2017-09
    • 2018-01
    • 2018-07
    • 2018-08
    • 2018-09
    • 2018-12
    • 2019-01
    • 2019-02
    • 2019-03
    • 2019-04
    • 2019-05
    • 2019-06
    • 2019-07
    • 2019-08
    • 2019-09
    • 2019-10
    • 2019-11
    • 2019-12
    • 2020-01
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-09
    • 2020-10
    • 2020-11
    • 2021-04
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-04
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-09
    • 2023-10
    • 2023-12
    • 2024-02
    • 2024-04
    • 2024-05
    • 2024-06
    • 2025-02
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客