语句

  1. 赋值
  2. 局部变量与块(block
  3. 控制结构
  4. if then else
  5. while
  6. repeat
  7. 数字型for
  8. 泛型for
  9. breakreturn

  

  Lua支持的常规语句基本上与C语言或Pascal语言中所支持的那些语句差不多。这些语句包括赋值、控制结构和过程调用。另外,Lua还支持一些不太常见的语句,例如多重赋值和局部变量声明。

  

  • 赋值

  1. a = "hello" .. "world"
  2. t = { n = 0 }
  3. t.n = t.n + 1

  Lua允许“多重赋值”,也就是一下子将多个值赋予多个变量。每个值或每个变量之间以逗号分隔。

  1. a, b = 10, 2*x -- a10b2*x

  在多重赋值中,Lua先对等号右边的所有元素求值,然后才执行赋值。这样便可以用一句多重赋值来交互两个变量了。

  1. x, y = y, x -- 交换xx
  2. a[i], a[j] = a[j], a[i] -- 交换a[i]与a[j]

  Lua总是会将等号右边值的个数调整到与左边变量的个数相一致。规则是:若值的个数少于变量的个数,那么多余的变量会被赋予nil;若值的个数更多的话,那么多余的值会被“静悄悄”丢弃掉:

  1. a, b, c = 0, 1
  2. print(a, b, c) --> 0 1 nil
  3. a, b = a+1, b+1, b+2 -- 其中b+2会被忽略
  4. print(a, b) --> 1 2
  5. a, b, c = 0
  6. print(a, b, c) --> 0 nil nil

  

  • 局部变量与块(block)

  相对于全局变量,Lua还提供了局部变量。通过local语句来创建局部变量:

  1. x = 10 -- 全局变量
  2. local i = 1 -- 程序块中的局部变量
  3. while i <= x do
  4. local x = i*2 -- while循环体中的局部变量
  5. print(x) --> 2, 4, 6, 8, ...
  6. i = i + 1
  7. end
  8. if i > 20 then
  9. local x -- then中的局部变量
  10. x = 20
  11. print(x+2) -- 如果测试成功会打印22
  12. else
  13. print(x) --> 10 (全局变量)
  14. end
  15. print(x) --> 10 (全局变量)

    在交互模式中每行输入内容自身就形成了一个程序块。为了解决这个问题,可以显式地界定一个块,只需将这些内容放入一对关键字do-end中即可。每当输入了do时,Lua就不会单独地执行后面每行的内容,而是直至遇到一个相应的end时,才会执行整个块的内容。

  如果需要更严格地控制某些局部变量的作用域时,这些do块也会有所帮助:

  1. do
  2. local a = 1
  3. local b = 2
  4. end -- ab的作用域至此结束

  

  • 控制结构

  Lua提供了一组传统的、小巧的控制结构,包括用于条件执行的if,用于迭代的whilerepeatfor。所有的控制结构都有一个显式的终止符:ifforwhileend作为结尾,repeatuntil作为结尾。

  控制结构中的条件表达式可以是任何值,Lua将所有不是falsenil的值视为“真”。

  

   if then else

  1. if a < 0 then a = 0 end
  2. if a < b then return a else return b end
  3. if op == "+" then
  4. r = a + b
  5. elseif op == "-" then
  6. r = a - b
  7. elseif op == "*" then
  8. r = a * b
  9. elseif op == "\" then
  10. r = a / b
  11. else
  12. error("invalid operation")
  13. end
  Lua不支持switch语句。

  

   while

  1. local i = 1
  2. while a[i] do
  3. print(a[i])
  4. i = i + 1
  5. end

  

   repeat

  一条repeat-until语句重复执行其循环体直到条件为真时结束。循环体至少会执行一次。

  1. repeat
  2. line = io.read()
  3. until line ~= ""
  4. print(line)
  与其他大多数语言不同的是,在Lua中,一个声明在循环体中的局部变量的作用域包括了条件测试:
  1. local sqr = x/2
  2. repeat
  3. sqr = (sqr + x/sqr)/2
  4. local error = math.abs(sqr^2 - x)
  5. until error < x/10000 -- 在此仍可以访问error

  

   数字型 for

  for语句有两种形式:数字型for和泛型for

  数字型for的语法如下:

  1. for var=exp1, exp2,exp3 do
  2. <执行体>
  3. end

  varexp1变化到exp2,每次变化都以exp3作为步长(step)递增var,并执行一次“执行体”。第三个表达式是可选的,若不指定的话,Lua会将步长默认为1。

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

  如果不想给循环设置上限的话,可以使用常量math.huge

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

  首先,for的3个表达式是在循环开始前一次性求值的。例如,上例中的f(x)只会执行一次。其次,控制变量会被自动地声明为for语句的局部变量,并且仅在循环体内可见。

  

   泛型for

  泛型for循环通过一个迭代器函数来遍历所有值:

  1. -- 打印数组a的所有值
  2. for i,v in ipairs(a) do print(v) end

  Lua的基础库提供了ipairs,这是一个用于遍历数组的迭代器函数。在每次循环中,i会被赋予一个索引值,同时v被赋予一个对应于该索引的数组元素值。

  1. -- 打印table t中所有的key
  2. for k in pairs(t) do print(k) end
  迭代table元素的(pairs)、迭代数组元素的(ipairs)、迭代字符串中单词的(string.gmatch)等。

  

  泛型for循环与数字型for循环有两个相同点:

  1. 循环变量是循环体的局部变量;
  2. 绝不应该对循环变量作任何赋值。
  1. -- 例:
  2. days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}
  3. -- 需要创建如下talbe
  4. revDays = {["Sunday"] = 1, ["Monday"] = 2, ["Tuesday"] = 3, ["Wednesday"] = 4, ["Thursday"] = 5, ["Friday"] = 6, ["Saturday"] = 7}
  5. -- 则可以按如下实现
  6. revDays = {}
  7. for k, v in pairs(day) do
  8. revDays[v] = k
  9. end

  

  • break与return

  breakreturn语句用于跳出当前的块。  break语句用于结束一个循环,它只会跳出包含它的那个内部循环(forrepeatwhile),而不会改变外层的循环。在执行了break后,程序会在那个被跳出的循环之后继续执行。

  return语句用于从一个函数中返回结果,或者用于简单地结束一个函数的执行。任何函数的结尾处都有一句隐式的return。所以如果一个函数,它没有值需要返回,那么就无须在其结尾处添加return语句。  由于语法构造的原因,breakreturn只能是一个块的最后一条语句。或者是endelseuntil前的一条语句。

例如,准备调试一个函数,但又不想执行该函数的内容。在这种情况下,可以使用一个显式的do块来包住一条return语句:

  1. funtion foo()
  2. return --<< 语法错误
  3. -- 在以下个块中return就是最后一条语句
  4. do return end -- OK
  5. <其他语句>
  6. end

?