`
hulianwang2014
  • 浏览: 726375 次
文章分类
社区版块
存档分类
最新评论
  • bcworld: 排版成这样,一点看的欲望都没有了
    jfinal

Lua基础 语句

 
阅读更多

Lua支持大多数传统的语句,跟C语言和Pascal差不多。传统的语句包括:赋值,控制结构,流程调用等。Lua还支持一些不太传统的语句,例如多赋值(听起来有点怪,往下看就明白了)和局部变量声明(这个好像也是传统的吧)。


1. 赋值

赋值是改变一个变量的值或者table的域的最基本的方法:

a = "hello" .. "world"
t.n = t.n + 1

Lua支持多赋值,多个值对应于多个变量,值和变量都分别用逗号','隔开。

a, b = 10, 20

在上面的语句中,得到的结果为a=10, b=20。


在多赋值语句中,Lua首先计算出所有的值,然后才会做赋值操作。因此,我们可以利用多赋值语句交换两个变量的值,如下:

x, y = y, x               -- swap 'x' for 'y'
a[i], a[j] = a[j], a[i]   -- swap 'a[i]' for 'a[j]'


Lua总是根据变量的数目来纠正值的数目:当变量的数目较多时,多出来的变量赋值为nil,相反,如果值的数目过多,那么多于的值会被丢弃:

a, b, c = 0, 1
print(a, b, c)        --> 0 1 nil
a, b = a+1, b+1, b+2  -- value of b+2 is discarded
print(a, b)           --> 1 2
a, b, c = 0
print(a, b, c)        --> 0 nil nil

上面的例子中,最后一条赋值语句是一个常犯的错误。如果要初始化一系列的变量为0,那么必须为每一个变量提供一个值。

a, b, c = 0, 0, 0
print(a, b, c)   --> 0 0 0

上面的例子,基本是人为的写出来说明多赋值的用法,在程序中,我们通常是不用多赋值语句来对一系列不相干的变量在同一行上进行赋值。多赋值操作在执行速度上不如同样结果的单赋值语句。但是,有时我们确实需要使用多赋值语句,例如上面的交换两个变量的值。还有一个用途是,可以获取函数的多个返回值。这种情况下,就是一个表达式为多个变量提供值。例如,a, b = f(),对函数f的调用返回两个值:a得到第一个,b得到第二个。


2. 局部变量和语句块

除了全局变量,Lua也支持局部变量。可以用local来创建局部变量

j = 10          -- global variable
local i = 1    --  local variable

跟全局变量不同,局部变量有作用域,只在它被声明的域内有效。域可以是一个控制结构,一个函数,或者代码块(变量声明的文件或者代码块)

x = 10
local i = 1           -- local to the chunk

while i <= x do
     local x = i*2    -- local to the while body
     print(x)         --> 2, 4, 6, 8, ...
     i = i + 1
end

if i > 20 then
     local x          -- local to the then body
     x = 20
     print(x + 2)     --(would print 22 if test succeeded)
else
    print(x)          --> 10 (the global one)
end

print(x)              --> (the global one)

如果上面的示例在交互模式下运行,可能会得不到预期的结果。在交互模式下,每一行是一个块。一旦你输入示例的第2行(local i = 1),Lua立刻运行它并且在下一行开始一个新的块。那时,local声明已经无效。当然,解决这个问题的办法肯定是有的。我们可以用do-end来显式地对整个块取消限制。只要你输入了do,那么命令只有在得到相对于的end时才会完成,因此Lua不会自己执行每一行。

在你想更好的控制局部变量的作用域时,do语句块是非常好用的:

do
    local a2 = 2*a
    local d = (b^2 - 4*a*c)^(1/2)
    x1 = (-b + d)/a2
    x2 = (-b - d)/a2
end                                -- scope of 'a2' and 'd' ends here
print(x1, x2)

尽可能的使用局部变量,是一个好的编程方式。局部变量可以使你避免用很多多余的全局变量名字导致的程序混乱。除此之外,局部变量的访问速度要比全局变量快。还有,局部变量在超出作用域后会自动失效,垃圾收集器会释放掉它占用的空间。


Lua将局部变量声明看成是语句。这样,你可以在任何地方code局部变量声明。局部变量的作用域,从它声明的地方开始生效,到语句块结束时失效。每条声明语句可以包含一个初始化,像常规的初始化语句一样:多余的值被丢弃,多余的变量赋值为nil。如果声明不包含初始化赋值,那么就会默认初始化为nil:

local a, b = 1, 20
if a < b then
    print(a)    --> 1
    local a     -- '=nil' is implicit
    print(a)    --> nil
end
print(a, b)     -->1 10

一个很常用的Lua语句:

local foo = foo

这句代码创建一个局部变量foo,并且用全局变量foo的值来对它进行初始化。(局部的foo在声明后可见)。有时,语句块想保护foo的值,防止后来它的值被其他函数改变,这种情况下,这条语句就很有用了;当然,也可以加快对foo的访问速度。


因为很多语句强制要求所有的局部变量都必须在一个块的开始处进行声明,一些人会认为在代码块中间进行局部变量声明不是好的编程风格。但是,恰恰相反:当你要用的时候再声明它,你总是会附带一个初始化的赋值语句(这样你就很少会忘记变量初始化)。除此之外,也可以缩小变量的作用域,增强代码可读性。


3.控制结构

Lua提供了一些传统的控制结构,if条件执行,while,repeatfor 迭代执行。所有的控制结构都有一个显式的结束符:endifforwhile的结束符;untilrepeat结构的结束符。


控制语句的条件表达式可能是任意值,Lua将falsenil看作是false,其他所有都是true


if then else

if语句检查它的条件表达式,根据结果来执行then-part或者else-part。else-part是可选的。

if a < 0 then a = 0 end

if a < b then return a else return b end

if line > MAXLINES then
    showpage()
    line = 0
end

要写嵌套的if,可以使用elseif。它类似于else if,但是这样可以省略不写多个end

if op == "+" then
    r = a + b
elseif op == "-" then
    r = a - b
elseif op == "*" then
    r = a * b
elseif op =="/" then
    r = a / b
else
    error("invalid operation")
end

Lua没有switch语句,因此上面这样长的if语句是比较平常的。


while

while检查条件表达式,如果条件为false,那么循环停止;否则,Lua运行循环体。然后重复这个过程。

local i = 1
while a[i] do
    print(a[i])
    i = i + 1
end


repeat

从名字就可以看出,repeat-until语句会执行它的循环体,直到它的条件表达式为true。条件表达式实在循环体之后才检查,因此,循环体至少会被运行一次。

-- print the first non-empty input line
repeat
    line = io.read()
until line ~= ""
print(line)

跟其他大多数语言不同,在Lua中,在循环体中声明的局部变量的作用域包括条件检查部分:

local sqr = x/2
repeat
    sqr = (sqr + x/sqr)/2
    local error =  math.abs(sqr^2 - x)
until error < x/10000                  -- 'error' still visible here


Numeric for

在Lua中,for循环有两种形式,numeric forgeneric for

numeric for的语法如下:

for var = exp1, exp2, exp3 do
    <something>
end

这个for循环,用var的值(从exp1到exp2,步进为exp3,exp3缺省默认为1)来执行something循环体。一些代表性的示例如下:

for i = 1, f(x) do print(i) end
for i = 10, 1, -1 do print(i) end

如果你想无上限的不停的循环,那么你可以用常量math.huge

for i = 1, math.huge do
    if (0.3*i^3 - 20*i^2 - 500 >= 0) then
        print(i)
        break
    end
end

for循环有一些技巧,我们要学习它们以便更好地使用for循环。第一,3个表达式exp1,exp2,exp3只会在循环开始的时候被计算1次。例如,在之前的示例中,f(x)只被调用一次。第二,控制变量被for语句自动声明为局部变量,并且只在循环中有效。下面的示例说明了一个代表性的错误,认为控制变量i在循环结束后仍然有效:

for i = 1, 10 do print(i) end
max = i     -- probably wrong! 'i' here is global

如若在循环结束后需要知道控制变量的是值,那么就必须将它的值保存到另外的变量中:

-- find a value in a list
local found  = nil
for i = 1, #a do
    if a[i] < 0 then
        found = i           -- save value of 'i'
        break
    end
end
print(found)

第三,绝对不能去更改控制变量的值,否则结果是不可预料的。如果想提前结束一个for循环,可以使用break。


Generic for

generic for循环从一个迭代函数中遍历所有的值

-- print all values of array 'a'
for i, v in ipairs(a) do print(v) end

Lua基础库提供了一个顺手的迭代函数ipairs。每次循环,i得到index,v得到与index相关的值。下面是一个类似的遍历table中的所有key的示例:

-- print all keys of table 't'
for k in pairs(t) do print(k) end

从表面上看很简单,但是generic for是比表面上看更强大的。使用合适的迭代器,我们可以遍历几乎任何东西。基础库提供了几个迭代器,迭代文件的行(io.lines),table的key-value对(pairs),数组中的条目(ipairs),string中的字符(string.gmatch),等等。当然,我们也可以自己写迭代器。尽管使用generic for很容易,但是写迭代器还是有一些技巧的,这个后面再讨论。


generic for和numeric for有两个相同点:控制变量是循环体中的局部变量,绝不能对控制变量赋值。


让我们再看一个更具体的generic for的示例,假设一个table如下:

days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}

现在,要把名字转换为其在一周中的位置,例如Sundays转换为1.你可以搜索table,找到相应的name。但是一个更有效率的方法是创建一个reverse table,表名为revDays,以name为key,number为值,看起来应该如下:

revDays = {["Sundays"] = 1, ["Mondays"] = 2, 
           ["Tuesday"] = 3, ["Wednesday"] = 4,
           ["Thursday"] = 5, ["Friday"] = 6, 
           ["Saturday"] = 7}

那么,你只需要以name为key从revDays中取值就可以了

x = "Tuesday"
print(revDays[x])      --> 3

当然,我们不需要手动声明这个revDays,我们可以根据原来的Days来创建它:

revDays = {}
for k, v in pairs(days) do
    revDays[v] = k
end

break 和 return

breakreturn语句可以使程序跳出循环


我们用break语句结束一个循环,结束包含它的最内层的循环,这个跟C是类似的。不能在循环体外使用breakbreak后,程序继续从跳出的循环部分继续执行。


return语句从函数返回结果,或者简单地只是结束一个函数。在函数的末尾都有一个隐式的return,因此,如果函数正常结束,不返回任何值,就没必要显式地调用一次return


由于一些语法限制,breakreturn语句只能作为一个语句块的最后一句(这个在5.2版本已经没有限制了)。下面是一个示例:

local i = 1
while a[i] do
    if a[i] == v then break end
    i = i + 1
end

有时候,在语句块的中间return或者break也很有必要,例如调试的时候(如下示例),那可以用do end来显示构造一个语句块

function foo()
    return       --<< SYNTAX ERROR
    -- 'return' is the last statement in the next block
    do return end          -- ok
    <other statements>
end



水平有限,如果有朋友发现错误,欢迎留言交流。

分享到:
评论

相关推荐

    Lua 基础教程(八)条件语句.pdf

    ### Lua基础教程(八)条件语句 #### 条件语句概述 在Lua编程语言中,条件语句是控制程序流程的一种基本机制。通过条件语句,可以根据不同的条件执行不同的代码块,从而实现程序逻辑的多样性。条件语句允许程序员...

    lua基础篇-流程控制语句

    Lua 基础篇 - 流程控制语句 在 Lua 编程语言中,流程控制语句是编写逻辑代码的基础构件之一。流程控制语句可以控制程序的执行流程,使程序具有灵活性和智能性。本节将介绍 Lua 语言中的流程控制语句,包括 if 语句...

    unity中需要的lua基础

    1. **Lua基础语法**:Lua是一种简洁、易读的脚本语言,它的基本语法包括变量(全局和局部)、数据类型(如数值、字符串、表、布尔值和nil)、运算符、控制结构(如if语句、while循环、for循环)等。理解这些基础是...

    Lua 基础教程(七)循环语句.pdf

    ### Lua基础教程(七)循环语句 #### 一、引言 在程序设计中,循环是一种非常重要的控制结构,它允许我们重复执行一段代码,直至满足特定条件为止。Lua作为一种简洁而强大的脚本语言,提供了多种循环机制来满足...

    Lua基础语法

    Lua 基础语法 Lua 语言是一种轻量级、灵活、可扩展的脚本语言,它的语法设计简单易学,功能强大。下面是 Lua 语言的基础语法介绍。 注释 在 Lua 中,注释可以使用单行注释和多行注释。单行注释使用两个减号"--...

    脚本策划LUA基础入门基础培训

    ### 脚本策划LUA基础入门基础培训 #### 一、引言 脚本策划在游戏开发领域扮演着至关重要的角色,特别是在游戏逻辑和交互设计方面。本篇旨在为初学者提供关于脚本策划及LUA语言的基础知识,帮助他们更好地理解脚本...

    lua中文教程,从基础到深入的让你学习lua

    本教程旨在提供一个全面且深入的中文学习资源,帮助读者从零基础到熟练掌握Lua。 首先,我们从基础开始。Lua的核心概念包括变量、数据类型和控制结构。在Lua中,变量是动态类型的,无需预先声明。它支持五种基本...

    lua语法 lua学习新手 基础 经典

    基础语句 * print("Hello world"):输出 "Hello world" 字符串。 * 语句之间可以用分号 ";" 隔开,也可以用空白隔开。 控制语句 * If 语句:格式为 "if 条件 then ... elseif 条件 then ... else ... end"。 * ...

    LUA基础语法

    "LUA基础语法" LUA是一种轻量级的脚本语言,广泛应用于游戏、嵌入式系统...LUA基础语法包括变量、数据类型、运算符、控制语句、函数、表、面向对象编程和错误处理等方面。了解这些基础知识点对于学习LUA语言非常重要。

    Lua基础应用笔记

    ### Lua基础应用知识点详解 #### 一、Lua简介与特性 **Lua** 是一种轻量级的脚本语言,以其高效、简洁著称。它由标准C语言编写,并且源代码完全开放。Lua的设计初衷是为了方便地嵌入到各种应用程序中,以便为这些...

    Lua 基础教程(三)基本语法.pdf

    ### Lua基础教程(三)基本语法 #### 交互模式编程 Lua支持一种称为**交互模式**的功能,允许用户逐行输入指令并立即查看执行结果。要启动交互模式,可以通过命令行使用`lua -i`或者仅使用`lua`命令。 ##### 启动...

    lua基础教程合集,适合初学者

    ### Lua基础教程合集知识点详解 #### 一、概览 **Lua**是一种轻量级、高效的脚本语言,常用于游戏开发、嵌入式系统等领域。本教程旨在为初学者提供一个全面的学习路径,从环境搭建到核心概念的讲解。 #### 二、...

    通过例子学LUA

    本文档是通过实例讲解LUA的教程,内容涵盖了LUA的基础知识和实践操作。文档结构图清晰易懂,使读者快速入门LUA语言。 第一部分:LUA语言简介 LUA是一种完全免费的脚本语言,可以和C/C++语言紧密结合。LUA的官方...

    Lua 5.1.3.zip

    lua5.1.dll是lua.exe能够运行Lua代码的基础,因为解释器需要调用这个库中的函数来解析和执行Lua语句。如果你在Windows环境下运行Lua程序,这个库文件是必不可少的。 3. **luac.exe**:Lua的编译器,它将Lua源代码...

    LUA学习资料(包括Programming in Lua+Lua 5.1 参考手册+LUA5.0.2解释器)

    LUA解释器支持命令行参数,可以方便地进行脚本的加载、执行和调试,同时也可以直接交互式地输入和执行LUA语句。 学习LUA的过程中,掌握这些资源是至关重要的。《Programming in Lua》提供理论基础和实践指导,参考...

    LUA基础知识

    ### LUA基础知识详解 #### 一、引言 本文旨在为LUA编程初学者提供一份全面的基础知识指南。LUA作为一种轻量级的脚本语言,因其简洁高效的特性而在游戏开发、网页应用等领域得到了广泛的应用。文章将从LUA的基本...

    lua程序设计及lua中文手册

    2. 控制结构:Lua提供了if语句、while循环、for循环以及函数式编程中的do-end块来控制程序流程。 3. 函数与闭包:Lua中的函数是一等公民,可以作为参数传递、返回结果,甚至可以存储在变量中。闭包是Lua中实现函数...

    Lua程序设计.pdf_lua_nginx_

    一、Lua基础 Lua的基础部分涵盖了变量、数据类型、控制结构、函数、表(Lua的核心数据结构,类似于关联数组)等核心概念。变量在Lua中是动态类型的,可以存储任何类型的数据,包括整数、浮点数、字符串、布尔值以及...

    lua_Console lua解析器

    "lua_Console lua解析器"是一个针对Lua脚本的简易解析工具,旨在帮助用户执行和理解基础的Lua语句。这个解析器可能是用C++编写的,因为文件名中包含了"cLua.cpp"和"simple_main.cpp",暗示了它可能是C++实现的一个...

    lua中文手册lua-5.3-zh-manual.pdf

    这部分涵盖了Lua的词法约定、变量、语句、表达式和函数定义等基本概念。 8. 编程接口 包括栈操作、C闭包、注册表等底层功能。 9. 辅助库 提供了如数学、字符串处理、表操作等功能。 10. 标准库 标准库是Lua提供的...

Global site tag (gtag.js) - Google Analytics