• openresty开发系列16--lua中的控制结构if-else/repeat/for/while


    openresty开发系列16--lua中的控制结构if-else/repeat/for/while
    
    一)条件 - 控制结构 if-else
    if-else 是我们熟知的一种控制结构。Lua 跟其他语言一样,提供了 if-else 的控制结构。
    
    1)单个 if 分支 型
    
    if 条件 then
      --body  
    end
    条件为真 ,执行if中的body
    -----------------------
    x = 10
    if x > 0 then
        print("分支一")
    end
    ----
    x = 10
    if (x > 0) then
        print("分支一")
    end
    
    运行输出:分支一
    
    2)两个分支 if-elseif 条件 then
      --条件为真 执行此body  
    else
      --条件为假 执行此body
    end
    ----------
    x = 10
    if x > 0 then
        print("分支一")
    else
        print("分支二")
    end
    运行输出:分支一
    
    3)多个分支 if-elseif-elseif 条件一 then
      --条件为真 执行此body  
    elseif  条件二  then
      .....
    elseif  条件三  then
      .....
    else
      --条件为假 执行此body
    end
    
    
    score = 90
    if score == 100 then
        print("分支一")
    elseif score >= 60 then
        print("分支二")
    --此处可以添加多个elseif
    else
        print("分支三")
    end
    运行输出:分支二
    
    与 C 语言的不同之处是 elseif 是连在一起的,若将 elseif 写成 "else if" 则相当于在 else 里嵌套另一个 if 语句,如下代码:
    score = 0
    if score == 100 then
        print("分支一")
    elseif score >= 60 then
        print("分支二")
    else
        if score > 0 then
            print("分支三")
        else
            print("分支四")
        end --与上一示例代码不同的是,此处要添加一个end
    end
    运行输出:分支四
    
    
    二)循环 - while 型控制结构
    Lua 跟其他常见语言一样,提供了 while 控制结构,语法上也没有什么特别的。但是没有提供 do-while 型的控制结构,但是提供了功能相当的 repeat。
    while 型控制结构语法如下,当表达式值为假(即 false 或 nil)时结束循环。也可以使用 break 语言提前跳出循环。
    
    while 条件表达式 do
    --body
    end
    
    示例代码,求 1 + 2 + 3 + 4 + 5 的结果
    
    x = 1
    sum = 0
    
    while x <= 5 do
        sum = sum + x
        x = x + 1
    end
    print(sum)  -->output 15
    
    continue继续执行,lua是没有这个概念
    
    break 终端循环,lua是有的
    
    值得一提的是,Lua 并没有像许多其他语言那样提供类似 continue 这样的控制语句用来立即进入下一个循环迭代(如果有的话)。因此,我们需要仔细地安排循环体里的分支,以避免这样的需求。
    没有提供 continue,却也提供了另外一个标准控制语句 break,可以跳出当前循环。例如我们遍历 table,查找值为 11 的数组下标索引:
    
    local t = {1, 3, 5, 8, 11, 18, 21}
    
    local i = 1
    
    while i < #t do
        if 11 == t[i] then
            print("index[" .. i .. "] have right value[11]")
            break
        end
      
      i = i + 1;
    end
    
    三)循环 - repeat 控制结构
    
    repeat  ---重复执行
        --body
    until 条件       条件为真时就结束
    
    1)until的条件表达式  为真 就结束
    
    2)repeat until 控制结构 ,他至少会执行一遍
    
    
    Lua 中的 repeat 控制结构类似于其他语言(如:C++ 语言)中的 do-while,但是控制方式是刚好相反的。简单点说,执行 repeat 循环体后,直到 until 的条件为真时才结束,而其他语言(如:C++ 语言)的 do-while 则是当条件为假时就结束循环。
    以下代码将会形成死循环:
    x = 10
    repeat
        print(x)
    until false
    该代码将导致死循环,因为until的条件一直为假,循环不会结束
    除此之外,repeat 与其他语言的 do-while 基本是一样的。同样,Lua 中的 repeat 也可以在使用 break 退出。
    
    
    
    四)for 控制结构
    
    for 语句有两种形式:数字 for 和范型 for1)数字型 for 的语法如下:
    for var = begin, finish, step do
        --body
    end
    关于数字 for 需要关注以下几点: 
    1.var 从 begin 变化到 finish,每次变化都以 step 作为步长递增 var 
    2.begin、finish、step 三个表达式只会在循环开始时执行一次 
    3.第三个表达式 step 是可选的,默认为 1 
    4.控制变量 var 的作用域仅在 for 循环内,需要在外面控制,则需将值赋给一个新的变量 5.循环过程中不要改变控制变量的值,那样会带来不可预知的影响
    
    for i = 1, 5 do
      print(i)
    end
    
    -- output:
    1
    2
    3
    4
    5
    
    for i = 1, 10, 2 do
      print(i)
    end
    
    -- output:
    1
    3
    5
    7
    9
    
    
    for i = 10, 1, -1 do
      print(i)
    end
    
    -- output:
    10
    9
    8
    7
    6
    5
    4
    3
    2
    1
    
    如果不想给循环设置上限的话,可以使用常量 math.huge:
    for i = 1, math.huge do
        if (0.3*i^3 - 20*i^2 - 500 >=0) then
          print(i)
          break
        end
    end
    
    2for 泛型
    对lua的table类型进行遍历
    
    泛型 for 循环通过一个迭代器(iterator)函数来遍历所有值:
    -- 打印数组a的所有值
    local a = {"a", "b", "c", "d"}
    for i, v in ipairs(a) do
      print("index:", i, " value:", v)
    end
    
    -- output:
    index:  1  value: a
    index:  2  value: b
    index:  3  value: c
    index:  4  value: d
    Lua 的基础库提供了 ipairs,这是一个用于遍历数组的迭代器函数。在每次循环中,i 会被赋予一个索引值,同时 v 被赋予一个对应于该索引的数组元素值。
    
    下面是另一个类似的示例,演示了如何遍历一个 table 中所有的 key
    -- 打印table t中所有的key
    for k in pairs(t) do
        print(k)
    end
    
    pairs是可以把数组类型和哈希类型索引值,都会迭代出来
    
    
    对于泛型 for 的使用,再来看一个更具体的示例。假设有这样一个 table,它的内容是一周中每天的名称:
    local days = {
      "Sunday", "Monday", "Tuesday", "Wednesday",
      "Thursday", "Friday", "Saturday"
    }
    
    k v ===》 v  ,k
    
    
    现在要将一个名称转换成它在一周中的位置。为此,需要根据给定的名称来搜索这个 table。然而 在 Lua 中,通常更有效的方法是创建一个"逆向 table"。例如这个逆向 table 叫 revDays,它以 一周中每天的名称作为索引,位置数字作为值:
      local revDays = {
        ["Sunday"] = 1,
        ["Monday"] = 2,
        ["Tuesday"] = 3,
        ["Wednesday"] = 4,
        ["Thursday"] = 5,
        ["Friday"] = 6,
        ["Saturday"] = 7
      }
    
    
    
    接下来,要找出一个名称所对应的需要,只需用名字来索引这个 reverse table 即可:
    local x = "Tuesday"
    print(revDays[x])  -->3
    
    当然,不必手动声明这个逆向 table,而是通过原来的 table 自动地构造出这个逆向 table:
    
    local days = {
       "Monday", "Tuesday", "Wednesday", "Thursday",
       "Friday", "Saturday","Sunday"
    }
    
    local revDays = {}
    for k, v in pairs(days) do
      revDays[v] = k
    end
    
    -- print value
    for k,v in pairs(revDays) do
      print("k:", k, " v:", v)
    end
    
    -- output:
    k:  Tuesday   v: 2
    k:  Monday    v: 1
    k:  Sunday    v: 7
    k:  Thursday  v: 4
    k:  Friday    v: 5
    k:  Wednesday v: 3
    k:  Saturday  v: 6
    这个循环会为每个元素进行赋值,其中变量 k 为 key(12、...),变量 v 为 value("Sunday""Monday"、...)。
    值得一提的是,在 LuaJIT 2.1 中,ipairs() 内建函数是可以被 JIT 编译的,而 pairs() 则只能被解释执行。因此在性能敏感的场景,应当合理安排数据结构,避免对哈希表进行遍历。事实上,即使未来 pairs 可以被 JIT 编译,哈希表的遍历本身也不会有数组遍历那么高效,毕竟哈希表就不是为遍历而设计的数据结构。
    
    
    五)break,return 关键字
    
    1)break
    语句 break 用来终止 while、repeat 和 for 三种循环的执行,并跳出当前循环体, 继续执行当前循环之后的语句。下面举一个 while 循环中的 break 的例子来说明:
    -- 计算最小的x,使从1到x的所有数相加和大于100
    sum = 0
    i = 1
    while true do
        sum = sum + i
        if sum > 100 then
            break
        end
        i = i + 1
    end
    print("The result is " .. i)  -->output:The result is 14
    在实际应用中,break 经常用于嵌套循环中。
    
    2)return
      return 主要用于从函数中返回结果,或者用于简单的结束一个函数的执行。 
      return 只能写在语句块的最后,一旦执行了 return语句,该语句之后的所有语句都不会再执行。
    
      执行return方法,如果实在主函数体里面,不在语句块中;执行return  且没有返回值,之后的语句照样会执行
    
    
      若要写在函数中间,则只能写在一个显式的语句块内,参见示例代码:
    
    local function add(x, y)
        return x + y
    end
    
    local function is_positive(x)
        if x > 0 then
            return x .. " is > 0"
        else
            return x .. " is not > 0"
        end
    
        print("function end!")
    end
    
    --由于return只出现在前面显式的语句块,所以此语句不注释也不会报错
    --,但是不会被执行,此处不会产生输出
    
    
    sum = add(10, 20)
    print("The sum is " .. sum)  -->output:The sum is 30
    answer = is_positive(-10)
    print(answer)                -->output:-10 is is not > 0
    
    有时候,为了调试方便,我们可以想在某个函数的中间提前 return,以进行控制流的短路。此时我们可以将 return 放在一个 do ... end 代码块中,例如:
    
    local function add(x, y)
        print(1)
        return
        print(2)
    end
    --return 不放在语句块中,return 也没有返回值,不注释该语句,不会报错; 但会执行return之后的业务
    
    local function add(x, y)
        print(1)
        do return end
        print(2)
    end
  • 相关阅读:
    mysql 远程登陆不上
    hdu 5339 Untitled【搜索】
    SqlServer 书目
    passwordauthentication yes
    oracle 11g RAC ocfs2
    Oracle 11g RAC database on ASM, ACFS or OCFS2
    CentOS ips bonding
    Oracle 11g RAC features
    openStack 王者归来之 trivial matters
    openstack windows 2008 img
  • 原文地址:https://www.cnblogs.com/reblue520/p/11429776.html
Copyright © 2020-2023  润新知