zoukankan      html  css  js  c++  java
  • Lua基本语法

    1. 注释

    --[[ 函数返回两个值的...
    最大值 --]]
    

    2. 基本数据类型

    a = true
    type(a)  -- boolean
    type(nil)  -- nil
    

    2.1. string

    html = [[
    <html>
    <head></head>
    <body>
        <a href="http://www.runoob.com/">菜鸟教程</a>
    </body>
    </html>
    ]]
    print(html)
    

    字符串连接使用的是 .. ,如:

    > print("a" .. 'b')
    ab
    > print(157 .. 428)
    157428
    

    使用 # 来计算字符串的长度,放在字符串前面,如下实例:

    > len = "www.runoob.com"
    > print(#len)
    14
    > print(#"www.runoob.com")
    14
    

    2.1.1. 字符串函数

    菜鸟教程

    • string.upper(argument)

    • string.lower(argument)

    • string.gsub(mainString,findString,replaceString,num) # 替换

      > string.gsub("aaaa","a","z",3);
      zzza    3
      
    • string.find (str, substr, [init, [end]])

    • string.reverse(arg)

    • string.format(...)

    • string.char(arg...) # 将整型数字转成字符并连接

    • string.byte(arg[,int]) # 转换字符为整数值

    • string.len(arg)

    • string.rep(string, n)

      > string.rep("abcd",2)
      abcdabcd
      
    • string.gmatch(str, pattern)

    • string.match(str, pattern, init)

    2.2. table

    Lua 中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字或者是字符串。或者说,是数组和字典的结合体。

    -- table_test.lua 脚本文件
    a = {}
    a["key"] = "value"
    key = 10
    a[key] = 22
    a[key] = a[key] + 11
    for k, v in pairs(a) do
        print(k .. " : " .. v)
    end
    

    不同于其他语言的数组把 0 作为数组的初始索引,在 Lua 里表的默认初始索引一般以 1 开始。

    -- table_test2.lua 脚本文件
    local tbl = {"apple", "pear", "orange", "grape"}
    for key, val in pairs(tbl) do
        print("Key", key)
    end
    

    2.3. function

    function factorial1(n)
        if n == 0 then
            return 1
        else
            return n * factorial1(n - 1)
        end
    end
    
    print(factorial1(5))
    factorial2 = factorial1
    print(factorial2(5))
    

    function 可以以匿名函数(anonymous function)的方式通过参数传递:

    function testFun(tab,fun)
        for k, v in pairs(tab) do
            print(fun(k,v));
        end
    end
    
    tab = {key1="val1", key2="val2"}
    testFun(tab,
        function(key,val)  -- 匿名函数
            return key.."="..val;
        end
    )
    

    2.3.1. 索引

    对 table 的索引使用方括号 []。Lua 也提供了 . 操作。

    t[i]
    t.i                 -- 当索引为字符串类型时的一种简化写法
    gettable_event(t,i) -- 采用索引访问本质上是一个类似这样的函数调用
    

    2.4. thread

    在Lua里,最主要的线程是协同程序(coroutine)。它跟线程(thread)差不多,拥有自己独立的栈、局部变量和指令指针,可以跟其他协同程序共享全局变量和其他大部分东西。

    线程跟协程的区别:线程可以同时多个运行,而协程任意时刻只能运行一个,并且处于运行状态的协程只有被挂起(suspend)时才会暂停。

    2.5. userdata(自定义类型)

    userdata 是一种用户自定义数据,用于表示一种由应用程序或 C/C++ 语言库所创建的类型,可以将任意 C/C++ 的任意数据类型的数据(通常是 struct 和 指针)存储到 Lua 变量中调用。

    3. 变量

    Lua 变量有三种类型:全局变量、局部变量、表中的域。

    Lua 中的变量全是全局变量,那怕是语句块或是函数里,除非用 local 显式声明为局部变量。

    局部变量的作用域为从声明位置开始到所在语句块结束。

    变量的默认值均为 nil。

    4. 循环

    4.1. while

    while(condition)
    do
       statements
    end
    

    4.2. 数值for循环

    for var=exp1,exp2,exp3 do
        statements
    end
    

    var 从 exp1 变化到 exp2,每次变化以 exp3 为步长递增 var,并执行一次 "执行体"。exp3 是可选的,如果不指定,默认为1。

    4.3. 泛型for循环

    --打印数组a的所有值
    a = {"one", "two", "three"}
    for i, v in ipairs(a) do
        print(i, v)
    end
    

    i是数组索引值,v是对应索引的数组元素值。ipairs 是Lua提供的一个迭代器函数,用来迭代数组。

    4.4. repeat...until 循环

    repeat
    statements
    until( condition )

    5. if

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

    要注意的是Lua中 0 为 true

    --[ 0 为 true ]
    if(0)
    then
        print("0 为 true")
    end
    

    if ... elseif ... else ...end

    if( 布尔表达式 1)
    then
       --[ 在布尔表达式 1 为 true 时执行该语句块 --]
    
    elseif( 布尔表达式 2)
    then
       --[ 在布尔表达式 2 为 true 时执行该语句块 --]
    
    elseif( 布尔表达式 3)
    then
       --[ 在布尔表达式 3 为 true 时执行该语句块 --]
    else
       --[ 如果以上布尔表达式都不为 true 则执行该语句块 --]
    end
    

    6. function

    optional_function_scope function function_name( argument1, argument2, argument3..., argumentN)
        function_body
        return result_params_comma_separated
    end
    

    Lua语言函数可以返回多个值,每个值以逗号隔开。

    6.1. 可变参数

    function add(...)
    local s = 0
      for i, v in ipairs{...} do  --> {...} 表示一个由所有变长参数构成的数组
        s = s + v
      end
      return s
    end
    
    print(add(3,4,5,6,7))  --->25
    

    有时候我们可能需要几个固定参数加上可变参数,固定参数必须放在变长参数之前:

    function fwrite(fmt, ...)  ---> 固定的参数fmt
        return io.write(string.format(fmt, ...))
    end
    
    fwrite("runoob
    ")       --->fmt = "runoob", 没有变长参数。
    fwrite("%d%d
    ", 1, 2)   --->fmt = "%d%d", 变长参数为 1 和 2
    

    通常在遍历变长参数的时候只需要使用 {…} ,然而变长参数可能会包含一些 nil ,那么就可以用 select 函数来访问变长参数了:

    • select('#', …) 返回可变参数的长度
    • select(n, …) 用于返回 n 到 select('#', …) 的参数

    调用select时,必须传入一个固定实参selector(选择开关)和一系列变长参数。如果selector为数字n,那么select返回它的第n个可变实参,否则只能为字符串"#",这样select会返回变长参数的总数。例子代码:

    do
        function foo(...)
            for i = 1, select('#', ...) do  -->获取参数总数
                local arg = select(i, ...)  -->读取参数
                print("arg", arg)
            end
        end
    
        foo(1, 2, 3, 4);
    end
    

    输出结果为:

    arg    1
    arg    2
    arg    3
    arg    4
    

    7. Lua 模块与包

    模块类似于一个封装库,从 Lua 5.1 开始,Lua 加入了标准的模块管理机制,可以把一些公用的代码放在一个文件里,以 API 接口的形式在其他地方调用,有利于代码的重用和降低代码耦合度。

    -- 文件名为 module.lua
    -- 定义一个名为 module 的模块
    module = {}
    
    -- 定义一个常量
    module.constant = "这是一个常量"
    
    -- 定义一个函数
    function module.func1()
        io.write("这是一个公有函数!
    ")
    end
    
    local function func2()
        print("这是一个私有函数!")
    end
    
    function module.func3()
        func2()
    end
    
    return module
    

    7.1. require 函数

    require("<模块名>")
    -- 或者
    require "<模块名>"
    
    require("module")
    
    print(module.constant)
    module.func3()
    

    或者给加载的模块定义一个别名变量,方便调用:

    local m = require("module")
    
    print(m.constant)
    m.func3()
    

    7.2. C 包

    Lua和C是很容易结合的,使用 C 为 Lua 写包。

    与Lua中写包不同,C包在使用以前必须首先加载并连接,在大多数系统中最容易的实现方式是通过动态连接库机制。

    Lua在一个叫 loadlib 的函数内提供了所有的动态连接的功能。这个函数有两个参数:库的绝对路径和初始化函数。所以典型的调用的例子如下:

    local path = "/usr/local/lua/lib/libluasocket.so"
    local f = loadlib(path, "luaopen_socket")
    

    loadlib 函数加载指定的库并且连接到 Lua,然而它并不打开库(也就是说没有调用初始化函数),反之他返回初始化函数作为 Lua 的一个函数,这样我们就可以直接在Lua中调用他。

    如果加载动态库或者查找初始化函数时出错,loadlib 将返回 nil 和错误信息。我们可以修改前面一段代码,使其检测错误然后调用初始化函数:

    local path = "/usr/local/lua/lib/libluasocket.so"
    -- 或者 path = "C:\windows\luasocket.dll",这是 Window 平台下
    local f = assert(loadlib(path, "luaopen_socket"))
    f()  -- 真正打开库
    

    一般情况下我们期望二进制的发布库包含一个与前面代码段相似的 stub 文件,安装二进制库的时候可以随便放在某个目录,只需要修改 stub 文件对应二进制库的实际路径即可。

    将 stub 文件所在的目录加入到 LUA_PATH,这样设定后就可以使用 require 函数加载 C 库了。

  • 相关阅读:
    python自动化测试基础篇no.1
    (易忘篇)java8新特性
    (易忘篇)java基础编程高级阶段5
    (易忘篇)java基础编程高级阶段4
    (易忘篇)java基础编程高级阶段2
    (易忘篇)java基础编程高级阶段1
    (易忘篇)java基础编程难点5
    (易忘篇)java基础编程难点4
    (易忘篇)java基础编程难点3
    (易忘篇)java基础编程难点2
  • 原文地址:https://www.cnblogs.com/brt2/p/13735830.html
Copyright © 2011-2022 走看看