zoukankan      html  css  js  c++  java
  • LUA基础

    循环

    for

    数值for循环, 语法:

    for var=exp1,exp2,exp3 do 

        <执行体> 

    end

    exp3是可选的,如果不指定,默认为1

    举例:

    for i = 0, #ret, 1

    do

             print("process: "..ret[i]["name"])

    end

    I 表示初始变量

    #ret 表示表的长度

    1表示每循环一次 I 的值增加多少,可以是负数

    泛型for循环,语法:

    for k, v in ipairs/pairs(a)

    do

              <执行体> 

    end

    举例:

    for k, v in pairs(ret)

    do

             print(k, v)

    end

    ret是一个表

    while

    语法:

    while(condition)

    do

       statements

    end

    condition 可以括号也可以不用括号

    举例:

    i = 0

    while true

    do

             if i > #ret then

                       break

             end

             print(i)

             i = i + 1

    end

    i = 0

    while i < #ret

    do

             print(i)

             i = i + 1

            

    end

    repeat

    语法:

    repeat

       statements

    until ( condition )

    condition 可以括号也可以不用括号

    举例:

    i = 0

    repeat

             print(ret[i]["name"])

             i = i + 1

    until (i > #ret)

    代码块

    do end

    关键字for 后面必须带do end

    关键字while后面必须带 do end

    then end

    关键字if后面执行的代码需要用then  end包起来

    function

    end

    关键字function定义的函数,结束要用end标识

    条件语句

    If语句

    if(布尔表达式) –括号可以不要

    then

       --[ 在布尔表达式为 true 时执行的语句 --]

    end

    if...else

    if(布尔表达式)

    then

       --[ 布尔表达式为 true 时执行该语句块 --]

    else

       --[ 布尔表达式为 false 时执行该语句块 --]

    end

    函数

    function

    Lua函数可以返回多个值

    Lua函数支持变参,然后通过for 来迭代访问参数

    function print_arg(...)

             local args = {...}

             for _, v in ipairs(args)

             do

                       print(v)

             end

    end

    print_arg(1, 2, "hello", "world")

    函数调用必须带括号, 除了单个参数的函数, 并且参数类型为字符串, 表构造器时, 可以不带括号

    Lua可以返回函数

    function print_arg(...)

             local args = {...}

             for _, v in ipairs(args)

             do

                       print(v)

             end

    end

    function return_function()

             return print_arg

    end

    _xxxprint_arg = return_function()

    _xxxprint_arg("hello", "sysnap")

    字符串

    string

    string库中所有的字符索引从前往后是1,2,...;从后往前是-1,-2,...

    string库中所有的function都不会直接操作字符串,而是返回一个结果

    string.byte(str, pos)可以把指定的位置的字符转为 ASCII 编码

    string.char(asc1, ...) 可以把ASCII 编码转为字符,比如string.char(104, 104)

    在lua5.1,同时也作为string类型的成员方法,既可以写成string.upper(s), 也可以s:upper()

    查找

    string.find(s, pattern,  [pos])

    第1个参数:源字符串

    第2个参数:待搜索之模式串

    第3个参数:A hint, 从pos位置开始搜索,可以不写,默认是1

    找到匹配返回:匹配串开始和结束的位置,否则返回nil,举例

    pos = 1;

    while true

    do

             s1, s2 = teststr:find("123", pos)

             if(s1 == nil) then

                       break;

             end

             print("find str pos: ", s1, s2)

             pos = s1 + 1;

    end

    模式

    字符大写表示补集,比如%W表示不是字母也不是数字

    .

    任意字符

    %s

    空白串

    %p

    标点,比如!,。?;

    %c

    控制字符,比如回车,换行符

    %d

    数字

    %x

    十六进制数字

    %z

    代表0的字符

    %a

    字母

    %l

    小写字母

    %u

    大写字母

    %w

    字母或者数字

    字符集

    []

    [%[%]]'匹配一对方括号。

    [01] 匹配二进制数字。

    [0-9a-fA-F] 匹配 16进制数,跟%x作用是一样的。

    [0-7] 表示 [01234567]。

    修饰符

    +

    匹配前一字符一次或多次

    *

    匹配前一字符0次或多次,最长匹配

    -

    匹配前一字符0次或多次,最短匹配.[ ] 里面-的意义见上面

    ?

    匹配前一字符0次或1次

    ^

    匹配字符串开头,如果放在[]里面,表示NOT意思

    $

    匹配字符串结尾

    转义字符

    %

    '%' 用作特殊字符的转义字符

    '%.' 匹配点;

    '%%' 匹配字符 '%'。

    转义字符 '%'不仅可以用来转义特殊字符,还可以用于所有的非字母的字符

    捕获: 在模式中,用小括号括起来的子模式,它在匹配发生的时候截取小括号内模式匹配到的字符串,然后保存下来,默认最多保存 32 个,可以理解是sscanf,  括起来的模式串只是告诉LUA这个串匹配到的内容要存起来并返回

    举例:

    pair = "name = Anna"

    _, _, key, value = string.find(pair, "(%a+)%s*=%s*(%a+)")

    print(key, value)    --> name  Anna

     

    date = "17/7/1990"

    _, _, d, m, y = string.find(date, "(%d+)/(%d+)/(%d+)")

    print(d, m, y)      --> 17 7 1990 

     

    s = "then he said: "its all right"!"

    a, b, quotedPart = string.find(s, "(["].-["])")

    print(quotedPart)    --> "its all right"

     

    一个空的捕获,也就是小括号里面什么内容也没有,它会返回当前字符串的比较操作进行到的位置

    s = "then he said: "it's all right"!"

    a, b, q = string.find(s, "()(["].-["])")

    print(q)    --> 15

    %后面接数字 1-9 表示用前面模式捕获的序号 1-9 对应的字符串来替换模式匹配的内容

    local s = "am+dmf"

    print(string.gsub(s, "()(m+)", "%1"))     -- a2+d5f     2

    --匹配到m的时候,位置是2,所以第一个捕获()输出是2,这时%1表示第一个捕获的值,这里是2,这里把m改---为2,接着继续匹配,匹配到dmf这个m的时候,位置是5,这时%1的值是5

     

    command{some text}将它们转换为XML风格的字符串:<command>some text</command>

    s = string.gsub(s, "\(%a+){(.-)}", "<%1>%2</%1>")

     

    举例

    s = "Deadline is 30/05/1999, firm"

    date = "%d%d/%d%d/%d%d%d%d"

    print(string.sub(s, string.find(s, date)))    --> 30/05/1999

    s = "hello world from Lua"

    for w in string.gmatch(s, "%a+") do

             print(w) –可以理解为匹配到一次之后,继续再匹配

               --string.match就只匹配一起

    end

    string.gsub("hello, up-down!", "%A", ".") 表示把任何非字母的字符替换为点号.

    *和-长匹配短匹配的差别

    test = "int x; /* x */ int y; /* y */"

    print(string.gsub(test, "/%*.*%*/", "<COMMENT>"))

        输出--> int x; <COMMENT>

    然而模式 '.-' 进行的是最短匹配,她会匹配 "/*" 开始到第一个 "*/" 之前的部分:

    test = "int x; /* x */ int y; /* y */"

    print(string.gsub(test, "/%*.-%*/", "<COMMENT>"))

        输出--> int x; <COMMENT> int y; <COMMENT>

    闭包

    先看一个例子

    function bibao()

             local var = 0

             function _subfunc()

                       var = var + 1

                       print("var: "..var)

                       return var

             end

             return _subfunc

    end

    f = bibao()

    f()

    f()

    输出是1, 2

    function bibao(var)

             --local var = 0

             function _subfunc()

                       var = var + 1

                       print("var: "..var)

                       return var

             end

             return _subfunc

    end

    f = bibao(2)

    f()

    f()

    输出是3,4

    这里变量var对于_subfunc而言,既不是全局变量,也不是局部变量,但又能被访问到,这个变量叫upvalue,upvalue实际指的是变量而不是值,这些变量可以在内部函数之间共享

    定义: 闭包是一个函数加上它可以正确访问的 upvalues,这个函数一般是一个匿名函数,并且定义在另一个函数内部;这个函数可以访问定义在外部函数内的成员变量,参数,以及全局函数

    闭包应用场景:

    1 作为函数的参数,比如gsub第三个参数可以指定一个function

    2 创建一个函数,即函数返回一个函数

    3 函数hook,比如io.open这个替换为我们的函数,保存老的函数做一些文件权限的检查

    4 实现迭代器,每个迭代器都需要在每次成功调用之间保持一些状态,这样才能知道它所在的位置及如何进到下一个位置。闭包刚好适合这种场景

    迭代器

    利用闭包实现的一个简单迭代器

    function iter(t)

             local pos = 0

             local maxn = table.getn(t)

             function get_item()

             pos = pos + 1

             if(pos <= maxn) then

             return t[pos]

             end

             return nil

             end

             return get_item

    end

    t = { "1sysnap", "2jim", "3green"}

    for k,_ in iter(t)

    do

             print(k)

    end

    local it = iter(t)

    local item = nil

    while true

    do

             item = it()

             if(item == nil) then

                       break

             end

             print(item)

    end

    元表

    背景:

    改变table的行为,每个行为关联了对应的元方法。比如俩个表相加

    当Lua试图对两个表进行相加时,先检查两者之一是否有元表,之后检查是否有一个叫"__add"的字段,若找到,则调用对应的值。"__add"等即时字段,其对应的值(往往是一个函数或是table)就是"元方法"

    __index元方法例子:

    t = { ["name"] = "sysnap"}

    print(t["name"])

    也可以写为t = { name = "sysnap"}

    print(t.name)

    再看一个元表的例子

    t = { name = "sysnap", ["foo"] = 2}

    mt = {}

    mt.__index = t

    newt = setmetatable({}, mt )

    --newt = setmetatable({}, {__index = t})

    print(newt.name, newt["foo"])

    Lua查找一个表元素时的规则,其实就是如下3个步骤:

    1.在表中查找,如果找到,返回该元素,找不到则继续

    2.判断该表是否有元表,如果没有元表,返回nil,有元表则继续。

    3.判断元表有没有__index方法,如果__index方法为nil,则返回nil;如果__index方法是一个表,则重复1、2、3;如果__index方法是一个函数,则返回该函数的返回值。

    t = { name = "sysnap", ["foo"] = 2}

    function newd(tb, key)

             print("key: ", key)

             return t[key]

    end

    mt = {}

    mt.__index = newd

    newt = setmetatable({}, mt )

    print(newt.name, newt["foo"])

    __tostring元方法例子: 控制表的输出

    function printTable(t, n)

             if "table" ~= type(t) then

                       return 0;

             end

             n = n or 0;

             local str_space = "";

             local str_return = "";

             for i = 1, n do

                       str_space = str_space.."  ";

             end

             str_return = (str_space.."{ ");

             for k, v in pairs(t) do

                       local str_k_v = str_space.."  ["..tostring(k).."] = ";

                       if "table" == type(v) then

                                str_return = str_return..str_k_v.." ";

                                printTable(v, n + 1);

                       else

                                str_k_v = str_k_v..tostring(v);

                                str_return = str_return..str_k_v.." ";

                       end

             end

             str_return = str_return..str_space.."}";

             return str_return

    end

    tb = { name = "sysnap", ["foo"] = 2}

    setmetatable(tb, {__tostring = printTable})

    print(tb)

    __call元方法: 类似C++的仿函数

    t = { name = "sysnap", ["foo"] = 2}

    t.__call = function (self, arg1) –因为是.访问,第一个参数是表本身,如果没传递参数这--里都可以直接为空

             print("hello table!"..arg1)

    end

    setmetatable(t, t)

    print(t(1))

    面向对象

    .调用函数: 句号要显示传递或接收self参数

    tb = { data1 = "hello", data2 = "world"}

    function tb.hello(self)

             print("hello world"..self.data1)

    end

    tb.hello(tb)

    :调用函数: 冒号默认传自己为参数,通过self关键字访问

    tb = { data1 = "hello", data2 = "world"}

    function tb:hello() –这里如果不用:是没办法用self关键字的

             print("hello world"..self.data1)

    end

    tb:hello()

    模块

    Lua 5.1提供了一个新函数module,囊括了上面一系列定义环境的功能。在开始编写一个模块时,可以直接用module("modname", package.seeall)来取代前面的设置代码。在一个模块文件开头有这句调用后,后续所有代码都不需要限定模块名和外部名字,同样也不需要返回模块table

  • 相关阅读:
    1.两数之和 力扣,水题
    525.连续数组 力扣 (前缀和)
    [LeetCode]56. Group Anagrams变位词分组
    界面布局注意(一)
    docker常用命令
    docker常用批量操作命令
    Golang package之math/rand
    (三)虚拟机与Linux新尝试——20155306白皎
    洛谷 P1383 codevs 3333 高级打字机
    BZOJ 1013 cogs 1845 [JSOI2008]球形空间产生器sphere
  • 原文地址:https://www.cnblogs.com/sysnap/p/5681655.html
Copyright © 2011-2022 走看看