zoukankan      html  css  js  c++  java
  • Lua学习笔记(四):基本语法

      Lua像C一样,几乎支持所有的传统语句:赋值语句、控制结构语句、函数调用等,同时也支持非传统的多变量赋值、局部变量声明。

      1、赋值语句:

      赋值是改变一个变量的值和改变表域的最基本的方法。

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

      Lua可以对多个变量同时赋值,变量列表和值列表的各个元素用逗号分开,赋值语句右边的值会依次赋给左边的变量。

    1 a, b = 10, 2*x        <-->        a=10; b=2*x

      遇到赋值语句Lua会先计算右边所有的值然后再执行赋值操作,所以我们可以这样进行交换变量的值:

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

      当变量个数和值的个数不一致时,Lua会一直以变量个数为基础采取以下策略:

     1 a. 变量个数 > 值的个数                按变量个数补足nil
     2 b. 变量个数 < 值的个数                多余的值会被忽略
     3 
     4 a, b, c = 0, 1 
     5 print(a,b,c)                --> 0   1   nil
     6 
     7 a, b = a+1, b+1, b+2        -- value of b+2 is ignored
     8 print(a,b)                    --> 1   2
     9 
    10 a, b, c = 0
    11 print(a,b,c)                --> 0   nil   nil

      上面最后一个例子是一个常见的错误情况,注意:如果要对多个变量赋值必须依次对每个变量赋值。

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

      多值赋值经常用来交换变量或者函数调用返回给变量:

    1 a, b = f()     --f()返回两个值,第一个赋给a,第二个赋给b

      2、局部变量与代码块(block)

      使用local创建一个局部变量,与全局变量不同,局部变量只在被声明的那个代码块内有效。代码块:指一个控制结构内,一个函数体,或者一个chunk (变量被声明的那个文件或者文本串)。

     1 x = 10
     2 local i = 1                -- local to the chunk
     3 
     4 while i<=x do
     5     local x = i*2            -- local to the while body
     6     print(x)                --> 2, 4, 6, 8, ...
     7     i = i + 1
     8 end
     9 
    10 if i > 20 then
    11     local x                -- local to the "then" body
    12     x = 20
    13     print(x + 2)
    14 else
    15     print(x)                --> 10  (the global one)
    16 end
    17 
    18 print(x)                    --> 10  (the global one)

      注意:如果在交互模式下上面的例子可能不能输出期望的结果,因为第二句local i=1是一个完整的chunk,在交互模式下执行完这一句后,Lua将开始一个新的chunk,这样第二句的i已经超出了他的有效范围。可以将这段代码放在do..end(相当于c/c++的{})块中。

      应该尽可能的使用局部变量,有两个好处:

      1). 避免命名冲突

      2).访问局部变量的速度比全局变量更快

      我们给block划定一个明确的界限:do..end内的部分。当你想更好的控制局部变量的作用范围的时候这是很有用的。

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

      3、控制结构语句

      控制结构的条件表达式结果可以是任何值,Lua认为false和nil为假,其他值为真。

     1 --if语句有三种形式:
     2 if conditions then 
     3     then-part
     4 end;
     5 
     6 if conditions then 
     7     then-part
     8 else
     9     else-part
    10 end;
    11 
    12 if conditions then 
    13     then-part
    14 elseif conditions then
    15     elseif-part
    16 ..                --->多个elseif
    17 else
    18     else-part
    19 end;
    20 
    21 
    22 --while语句:
    23 while condition do
    24     statements;
    25 end;
    26 
    27 --repeat-until语句:
    28 repeat
    29     statements;
    30 until conditions;

      for语句有两大类: 

      第一,数值for循环:

    1 for var=exp1,exp2,exp3 do
    2     loop-part
    3 end
    4 
    5 --for将用exp3作为step从exp1(初始值)到exp2(终止值),执行loop-part。其中exp3可以省略,默认step=1

      有一下几点需要注意:

      1).三个表达式只会被计算一次,并且是在循环开始前。

    1 for i=1,f(x) do
    2     print(i)
    3 end
    4 
    5 for i=10,1,-1 do
    6     print(i)
    7 end
    8 
    9 --第一个例子f(x)只会在循环前被调用一次

      2).控制变量var是局部变量自动被声明,并且只在循环内有效

     1 for i=1,10 do
     2     print(i)
     3 end
     4 max = i        -- probably wrong! 'i' here is global
     5 
     6 --如果需要保留控制变量的值,需要在循环中将其保存
     7 -- find a value in a list
     8 local found = nil
     9 for i=1,a.n do
    10     if a[i] == value then
    11         found = i            -- save value of 'i'
    12         break
    13     end
    14 end
    15 print(found)

      3).循环过程中不要改变控制变量的值,那样做的结果是不可预知的。如果要退出循环,使用break语句。

      第二, 范型for循环:

      范型for遍历迭代子函数返回的每一个值。

    1 -- print all values of array 'a' 
    2 for i,v in ipairs(a) do print(v) end
    3 
    4 -- print all keys of table 't'
    5 for k in pairs(t) do print(k) end

      范型for和数值for有两点相同:

      1).控制变量是局部变量

      2).不要修改控制变量的值

     1 --在看一个例子,假定有一个表:
     2 days = {"Sunday", "Monday", "Tuesday", "Wednesday",
     3                 "Thursday", "Friday", "Saturday"}
     4 
     5 --现在想把对应的名字转换成星期几,一个有效地解决问题的方式是构造一个反向表:
     6 revDays = {["Sunday"] = 1, ["Monday"] = 2, 
     7             ["Tuesday"] = 3, ["Wednesday"] = 4,
     8             ["Thursday"] = 5, ["Friday"] = 6,  
     9             ["Saturday"] = 7}
    10 
    11 --下面就可以很容易获取问题的答案了:
    12 x = "Tuesday" 
    13 print(revDays[x])            --> 3
    14 
    15 --我们不需要手工,可以自动构造反向表
    16 revDays = {} 
    17 for i,v in ipairs(days) do
    18     revDays[v] = i 
    19 end 

      4、break和return语句

      break语句用来退出当前循环(for,repeat,while)。在循环外部不可以使用。

      return用来从函数返回结果,当一个函数自然结束时,结尾会有一个默认的return。

      Lua语法要求break和return只能出现在block的结尾一句。如:

     1 local i = 1
     2 while a[i] do
     3     if a[i] == v then break end
     4     i = i + 1
     5 end
     6 
     7 --有时候为了调试或者其他目的需要在block的中间使用return或者break,可以显示的使用do..end来实现
     8 
     9 function foo ()
    10     return                --<< SYNTAX ERROR
    11     -- 'return' is the last statement in the next block
    12     do return end            -- OK
    13     ...                    -- statements not reached
    14 end
  • 相关阅读:
    oracle中Blob和Clob类型的区别
    为什么要分库分表
    Enable file editing in Visual Studio's debug mode
    SQL Server Dead Lock Log
    Debug .NET Framework Source
    SQL Server text field里面有换行符的时候copy到excel数据会散乱
    诊断和修复Web测试记录器(Web Test Recorder)问题
    Can't load Microsoft.ReportViewer.ProcessingObjectModel.dll
    'telnet' is not recognized as an internal or external command
    Linq to XML
  • 原文地址:https://www.cnblogs.com/atong/p/3844486.html
Copyright © 2011-2022 走看看