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
  • 相关阅读:
    MyCAT常用分片规则之分片枚举
    MySQL参数
    CentOS 7下MySQL服务启动失败的解决思路
    ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
    CHECK_NRPE: Received 0 bytes from daemon. Check the remote server logs for error messages.
    MyCAT实现MySQL的读写分离
    搭建Spark的单机版集群
    如何部署Icinga服务端
    MyCAT简易入门
    如何部署Icinga客户端
  • 原文地址:https://www.cnblogs.com/atong/p/3844486.html
Copyright © 2011-2022 走看看