lua 订阅
Lua [1]  是一个小巧的脚本语言。它是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个由Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo三人所组成的研究小组于1993年开发的。 其设计目的是为了通过灵活嵌入应用程序中从而为应用程序提供灵活的扩展和定制功能。Lua由标准C编写而成,几乎在所有操作系统和平台上都可以编译,运行。Lua并没有提供强大的库,这是由它的定位决定的。所以Lua不适合作为开发独立应用程序的语言。Lua 有一个同时进行的JIT项目,提供在特定平台上的即时编译功能。Lua脚本可以很容易的被C/C++ 代码调用,也可以反过来调用C/C++的函数,这使得Lua在应用程序中可以被广泛应用。不仅仅作为扩展脚本,也可以作为普通的配置文件,代替XML,ini等文件格式,并且更容易理解和维护。 [2]  Lua由标准C编写而成,代码简洁优美,几乎在所有操作系统和平台上都可以编译,运行。 [2]  一个完整的Lua解释器不过200k,在所有脚本引擎中,Lua的速度是最快的。这一切都决定了Lua是作为嵌入式脚本的最佳选择。 [2] 展开全文
Lua [1]  是一个小巧的脚本语言。它是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个由Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo三人所组成的研究小组于1993年开发的。 其设计目的是为了通过灵活嵌入应用程序中从而为应用程序提供灵活的扩展和定制功能。Lua由标准C编写而成,几乎在所有操作系统和平台上都可以编译,运行。Lua并没有提供强大的库,这是由它的定位决定的。所以Lua不适合作为开发独立应用程序的语言。Lua 有一个同时进行的JIT项目,提供在特定平台上的即时编译功能。Lua脚本可以很容易的被C/C++ 代码调用,也可以反过来调用C/C++的函数,这使得Lua在应用程序中可以被广泛应用。不仅仅作为扩展脚本,也可以作为普通的配置文件,代替XML,ini等文件格式,并且更容易理解和维护。 [2]  Lua由标准C编写而成,代码简洁优美,几乎在所有操作系统和平台上都可以编译,运行。 [2]  一个完整的Lua解释器不过200k,在所有脚本引擎中,Lua的速度是最快的。这一切都决定了Lua是作为嵌入式脚本的最佳选择。 [2]
信息
类    型
脚本语言
研究时间
1993年
外文名
lua
研究地点
巴西里约热内卢天主教大学
lua保存和运行
运行可以通过 Lua 的交互模式,也可以用记事本编辑代码保存为 .lua 的格式,通过 Lua 编译器运行。也可以通过第三方工具,将 Lua 打包独立运行。
收起全文
精华内容
参与话题
问答
  • Lua基础(一)

    千次阅读 多人点赞 2019-01-25 22:35:55
    目录Lua是什么Lua应用场景Lua和C#的区别print方法、单行/多行注释Lua命名规则(标识符)全局变量的使用和销毁Lua中的数据类型nil 空类型boolean 布尔类型number数字类型string字符串类型table表类型function函数...

    Lua是什么

    Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
    Lua 可以很方便的和其他程序进行集成(c++,c#,java等)


    Lua应用场景

    游戏开发
    独立应用脚本
    Web 应用脚本
    扩展和数据库插件如:MySQL Proxy 和 MySQL WorkBench
    安全系统,如入侵检测系统


    Lua和C#的区别

    Lua 可以在几乎所有的操作系统和平台进行编译运行,可以很方便的更新代码,更新了代码后,可以直接在手机上运行,不需要重新安装(比如热更新方案)

    C#只能在特定的操作系统中进行编译成dll文件,然后打包进安装包在其他平台(比如 Android、iOS),如若已经运行在移动平台上,不能更新替换已有的dll文件,除非重新下载安装包


    print方法、单行/多行注释

    print("Hello world")
    
    -- 用来表示单行注释
    
    --[[
    用来表示多行注释
    --]]
    
    

    Lua命名规则(标识符)

    1,不能以数字开头
    2,不能是关键字
    关键字比如:
    and//break//do//else//elseif//end//false//for//function等

    而且在 Lua 中大小写是敏感的,and 是关键字,And,AND 这是两个不同的标识符

    还有_XXX(_ABC)这种不推荐使用(是保留用法,在 Lua 中有特殊的用法)


    全局变量的使用和销毁

    Lua中变量不需要声明,可以直接使用,也不需要初始化,可以直接使用。
    对于没有初始化和声明的变量默认值为 nil(空类型,空值)

    b = nil
    

    把一个变量置空(nil),相当于没有使用过这个变量,Lua 会销毁 b 所占的内存


    Lua中的数据类型

    nil 这个最简单,只有值nil属于该类,表示一个无效值(在条件表达式中相当于false)。
    boolean 包含两个值:false和true。
    number 表示双精度类型的实浮点数
    string 字符串由一对双引号或单引号来表示
    function 由 C 或 Lua 编写的函数
    userdata 表示任意存储在变量中的C数据结构
    thread 表示执行的独立线路,用于执行协同程序
    table Lua 中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字或者是字符串。在 Lua 里,table 的创建是通过"构造表达式"来完成,最简单构造表达式是{},用来创建一个空表。

    在 Lua 中有一个 type 方法,它可以返回数据的类型,输出的是 string 字符串,比如:

    print(type("Hello world"))      --> string
    print(type(10.4*3))             --> number
    print(type(print))              --> function
    print(type(type))               --> function
    print(type(true))               --> boolean
    print(type(nil))                --> nil
    print(type(type(X)))            --> string
    

    nil 空类型

    没有声明和赋值的变量都是默认 nil 类型
    这个 nil 类型下面只有一个值 nil 值
    把一个变量赋值为 nil,表示回收并删除这个变量


    boolean 布尔类型

    这个下面只有两个值 true 和 false
    false 和 nil 都代表 false,其他任何值都代表 true(0和空字符串 Lua 也都认为是 true)


    number数字类型

    1,数字的表示方式
      4  0.4   4.45e-3  0.3e12  5E+20
    2,整数和小数都是 number 类型的
      type(3)    type(3.5)
    3,如果整数和小数的大小是一样的,那么 Lua 认为就是相等的
      1 == 1.0   -3 == -3.0  0.2e3==200
    4,如果我们想要区分整数和小数这两种类型,可以使用 math.type 函数
      math.type(3)  math.type(3.0)  integer  float
    5,1e3 表示一个小数
      1000.0
    6,支持16进制
      0xff  0x1A3  0x0.2


    string字符串类型

    定义:使用单引号或者双引号表示字符串

    1,替换字符串

        a="one string";
        b=string.gsub(a,"one","another")
        print(a)     --> one string
        print(b)     --> another string
    

    2,取得字符串的长度#

        print(#a)     --> 10
        print(#"good bye")     --> 8
    

    3,字符串组拼

        "Hello".."World"
        "result is"..3
    

    table表类型

    表在 Lua 中是一个非常重要的数据结构,也是最有权力的。
    1、我们可以使用表表示数组,集合,字典…
    2、Lua table 使用关联型数组,你可以用任意类型的值来作数组的索引,但这个值不能是 nil。
    3、Lua table 是不固定大小的,你可以根据自己需要进行扩容。
    4、表既不是值类型也不是变量,它是对象。
    5、Lua 也是通过 table 来解决模块(module)、包(package)和对象(Object)的。 例如 string.format 这里其实 string 并不是一个类。在 Lua 中没有类,Lua 中使用 table 实现类、面向对象这些概念。

        tab1 = {} --空表   {}构造表达式
        
        tab2 = {key1=100,key2="value2"} --初始化一个表
       
        tab2[1] = "Lua"   -- 指定值
        
        print(tab1)
        print(tab1.key)
        
        print(tab2.key1)
        print(tab2["key1"])
        
        tab2 = nil  -- 移除引用 Lua 的垃圾回收会释放内存
        
        tab3 = {"apple","pear","orange","grape"}
        
        print(tab3[2])
        print(tab3["2"])
        
        for key,val in pairs(tab3) do
        	print(key..":"..val)
        end
        
        for key,val in pairs(tab2) do
        	print(key..":"..val)
        end
    

    关于表的自动垃圾回收:当我们创建一个表 a 并设置元素,然后将 a 赋值给 b,则 a 与 b 都指向同一个内存。如果 a 设置为 nil ,则 b 同样能访问 table 的元素。如果没有指定的变量指向 a,Lua的垃圾回收机制会清理相对应的内存。


    function函数

    比如一个求阶乘的函数

    function fact(n)
    	if n==1 then
    		return n;
    	else
    		return n*fact(n-1);
    	end
    end
    
    print(fact(3))
    print(fact(5))
    
    fact2 = fact
    print(fact2(5))
    

    另一种,关于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
    );
    
    执行结果为:
    key1 = val1
    key2 = val2
    

    thread和userdata类型

    在 Lua 里,最主要的线程是协同程序(coroutine)。它跟线程(thread)差不多,拥有自己独立的栈、局部变量和指令指针,可以跟其他协同程序共享全局变量和其他大部分东西。
    线程跟协程的区别:线程可以同时多个运行,而协程任意时刻只能运行一个,并且处于运行状态的协程只有被挂起(suspend)时才会暂停。

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


    全局变量和局部变量的声明和使用

    全局变量

    a = 5 
    print(type(a))   --> number
    --类型可变
    a = "Hello"
    print(type(a))   --> string
    

    局部变量

    --局部变量的销毁是在所在语句块结束
    local b = 10
    print(b)
    
    function test()
    	c = 5
    	local d = 6
    end
    
    test()
    
    print(c,d)
    
    do
    	local a = 10
    	b =11
    	print(a,b)
    end
    
    print(a,b)
    

    多变量赋值

    a,b = 10,20   -- a = 10 b = 20
    
    a,b,c = 10,20,"Hello"
    print(a,b,c)
    
    a,b = b,a   -- a = b  b = a 也就是 变量交换值
    print(a,b)
    
    a,b = 10,20,30   --多的值自动略去
    print(a,b)
    
    a,b,c = 20,30   --没有值赋值 nil
    print(a,b,c)
    
    function test()
    	return 40,50
    end
    
    a,b = test()   --返回多个值 并获取
    print(a,b)
    
    

    循环

    1,while循环
    2,for循环
    3,repeat unitl (do while)


    while循环

    while (condition) 
    do
    	statements
    end
    
    a = 1
    while (a<=20) 
    do
    	if (a%2==1) then
    		print(a)
    	end
    	a=a+1
    end
    

    for循环

    1,数值for循环

    for var=start,end,step do
    循环体
    end
    这里var会从start变化到end,每次变化一step进行

    for i=1,10,2 do
    	print(i)
    end
    
    for i=20,1,-3 do
    	print(i)
    end
    

    2,泛型for循环

    tab1 = {key1="value1",key2="value2"}
    
    for k,v in pairs(tab1) do
    	print(k,v)
    end
    
    tab2 = {"apple","橡胶","西瓜","猕猴桃"}
    
    for k,v in pairs(tab2) do
    	print(k,v)
    end
    

    repeat until循环

    repeat
    循环体
    until(condition)

    a = 1
    repeat
    	print(a)
    	a=a+1
    until(a>10)
    

    循环嵌套

    for i=1,10 do
    	for j=1,i do
    		print(i)
    	end
    end
    
    
    for i=1,10 do
    	j=1
    	while j<=i do
    		print(i)
    		j=j+1
    	end
    end
    

    流程控制

    if (布尔表达式) then
    为true的时候要执行的代码
    end

    if(布尔表达式)then
    为true的时候要执行的代码
    else
    为false的时候要执行的代码
    end

    if (布尔表达式) then
    //1
    elseif (布尔表达式) then
    //2
    else
    //3
    end

    -----
    if (0) then
    	print(0)
    end
    -----
    a  = 10
    if (a>10) then
    	print("a大于10")
    end
    -----
    if a<=10 then
    	print("a小于等于10")
    end
    -----
    if (b) then
    	print("b不为空")
    else
    	print("b为空")
    end
    -----
    a = 100
    if (a<=50) then
    	print("a<=50")
    elseif (a<=100) then
    	print("a<=100")
    elseif (a<=150) then
    	print("a<=150")
    else
    	print("上面三种情况都不满足")
    end
    
    

    function用法特性总结

    [local] function functionName(arg1,arg2,arg3…argn)
              functionBody
              [return value1,value2…valuen]
    end

    local function max(num1,num2)
    	if(num1>num2)then
    		return num1
    	else
    		return num2
    	end
    end
    
    print( max(1,10) )
    
    --函数可以作为数据赋值   可以作为参数传递
    temp = max
    print(temp(40,3))
    -----
    myprint = function (param)
    	print("这个是我的打印函数"..param)
    end
    
    myprint(100)
    -----
    function add(num1,num2,printFun)
    	local res = num1+num2
    	printFun(res)
    end
    
    add(40,50,myprint)
    
    --lua里面的函数可以返回多个值
    

    可变参数 用 ... 三个点表示

    function average(...)
    	local arg = {...}
    	res = 0
    	for k,v in pairs(arg) do
    		res = res+v
    	end
    	-- #arg 取得参数的个数  	#"hello"
    	print(res/#arg)
    end
    
    average(10)
    average(1,30)
    average(3,8,90)
    average(5,67,7,8,3)
    

    运算符

    算术运算符:+ - * / % ^求幂 -

    关系运算符: == ~= > < >= <=

    
    if(a==b)then
    	print("a==b")
    else
    	print("a~=b")
    end
    -----
    if(a~=b)then
    	print("ab不相等")
    else
    	print("ab相等")
    end
    -----
    if(a<b)then
    	print("a小于b")
    else
    	print("a不小于b")
    end
    

    逻辑运算符 and or not
    a and b a ,b 都为true则结果为true
    a or b a,b中只要有一个为true,结果为true
    not a 非/取反

    print( 30>20 and 10>30)
    
    print( false or false  )
    
    print (not true)
    

    字符串操作

    str ="My name is MoGu! name"
    str2 =string.upper(str)
    str3 =string.lower(str)
    
    str4 =string.gsub(str,"i","123",5)
    
    index = string.find(str,"name",5) --返回所查找到的位置的索引
    
    str5=string.reverse(str)
    
    num1 = 5
    num2 = 10
    
    print(str,str2,str3,str4,index)
    print(str5)
    print("加法运算:"..num1.."+"..num2.."="..(num1+num2))
    username = "w3er4wwrfwer"
    password = "lkjlw3e4rl"
    print("select * from user where username = '"..username.."' and password ='"..password.."'")
    
    str6=string.format("加法运算:%d+%d=%d",num1,num2,(num1+num2))
    print(str6)
    str7 = string.format("select * from user where username='%s' and password ='%s'",username,password)
    print(str7)
    
    date = 2; month = 1; year = 2014
    print(string.format("日期格式化 %02d/%02d/%03d", date, month, year))
    
    s1 = string.char(97,98,99,100)
    i1 =string.byte("ABCD",4)
    i2 =string.byte("ABCD")
    print(s1,i1,i2)
    
    length1 = string.len("abc")
    length2 = #"abc"
    print(length1,length2)
    
    s2=string.rep("abcd",4)
    print(s2)
    
    for word in string.gmatch("Hello Lua user", "%a+") do
    	print(word)
    end
    

    数组

    Lua 数组的索引键值可以使用整数表示,数组的大小不是固定的。

    array = {"Lua","C#"}
    array[3]="Java"
    
    for i=1,3 do
    	print(array[i])
    end
    
    array = {}
    
    for i =-2,2 do
    	array[i]=i*3
    end
    
    for i=-2,2 do
    	print(array[i])
    end
    
    

    二维…多维数组

    array = { {"小明","小红"},{"小刘","小狼"},{"大明","大刘"},{"小赵","李四"} }  --4*2
    
    print(array[3][1])
    
    for i =1,4 do
    	for j=1,2 do
    		print(array[i][j])
    	end
    end
    
    array = {{},{},{}}
    
    for i = 1,3 do
    	array[i]={}
    	for j=1,2 do
    		array[i][j]=i*j
    	end
    end
    
    for i = 1,3 do
    	for j=1,2 do
    		print(array[i][j])
    	end
    end
    
    

    迭代器

    pairs迭代table,遍历表中所有的key跟value
    ipars按照索引从1开始,递增遍历,遇到nil值就停止

    array = {"Lua","C#","Java"}
    
    for k in pairs(array) do
    	print(k,v)
    end
    
    array[2]=nil
    
    for k,v in ipairs(array) do
    	print(k,v)
    end
    

    整体的结构

    for 变量列表 in 迭代函数,状态变量,控制变量  do
    	--循环体
    end
    

    1,调用迭代函数,(把状态变量和控制变量当做参数传递给迭代函数) 状态变量只会在第一次调用的时候赋值。
    2,如果迭代函数的返回值为nil,退出for循环;如果不是nil的话,把返回值赋值给变量列表,并执行循环体。

    自定义迭代函数,求平方

    function square(state,control)
    	if(control>=state) then
    		return nil
    	else
    		control=control+1
    		return control,control*control
    	end
    end
    
    for i,j in square,9,0 do
    	print(i,j)
    end
    

    表的基本

    mytable = {}
    
    mytable[1] = "Lua"
    
    mytable[1] = nil
    
    mytable = nil
    
    mytable = {}
    
    print( type(mytable) )
    
    mytable[1] = "Lua"
    mytable["name"]="siki"
    
    newtable = mytable
    
    print(newtable[1])
    print(mytable[1])
    
    newtable[1]="C#"
    
    print(newtable[1])
    print(mytable[1])
    
    newtable[2]="Java"
    
    print(mytable[2])
    
    
    mytable = nil
    
    print(mytable.name)
    print(newtable.name)
    
    newtable = nil
    

    表的基本操作

    --方法一般都是 table.xxxxmethod
    
    --Table连接
    mytable = {"Lua","C#","Java","C++","C","abc","ABC"}
    
    print( table.concat(mytable) )
    print( table.concat(mytable,",") )
    print( table.concat(mytable,",",2,4) )
    
    --Table插入   mytable[6]="PHP"
    mytable[#mytable+1]="PHP"
    print(mytable[#mytable])
    table.insert( mytable,"Javascript" )
    print(mytable[#mytable])
    table.insert(mytable,2,"Boo")
    print(mytable[2],mytable[3])
    
    --Table移除
    mytable[2]=nil
    print(mytable[2])
    table.remove(mytable,2)
    print(mytable[2])
    
    --Table排序
    mytable={34,32,34,2,45,45,435,6,4576,76,33,23,24,2343,21,2,2,2,2,2,2,2,2}
    
    print("排序前")
    
    for k,v in ipairs(mytable) do
    	print(k,v)
    end
    
    table.sort(mytable)
    print("排序后")
    
    for k,v in ipairs(mytable) do
    	print(k,v)
    end
    
    --自定义最大值方法
    function get_max_number(tab)
    	local mn = 0
    	for k,v in pairs(tab) do
    		if(mn<v) then
    			mn=v
    		end
    	end
    	return mn
    end
    
    print(  get_max_number(mytable) )
    
    

    模块

    Lua 的模块是由变量、函数等已知元素组成的 table,因此创建一个模块很简单,就是创建一个 table,然后把需要导出的常量、函数放入其中,最后返回这个 table 。

    module = {}
    
    module.var = "Name"
    
    module.func1 = function ()
    	print("这个是Module里面的函数")
    end
    
    function module.func1()
    	print("这个是Module里面的函数")
    end
    
    local function func2()
    	print("这个是局部函数fun2")  --相当于一个私有函数 private
    end
    
    function module.func3()
    	func2()
    	print("这个是全局函数func3")
    end
    
    return module
    
    

    那么如何使用它呢:

    --require "模块名"
    --require ("模块名")
    
    m = require "module"
    
    print(m.var)
    m.func1()
    m.func3()
    

    元表(Metatable)

    元表提供了让我们改变 table 的行为的能力,每个行为关联了对应的元方法,可理解为对表操作的扩展。

    mytable = {"Lua","Java","C#","C++"} --普通表
    mymetatable = {} --元表   元表扩展了普通表的行为
    
    mytable =setmetatable(mytable,mymetatable)
    print( mytable[3] )
    
    print(getmetatable(mytable))
    print(mymetatable)
    
    tab = setmetatable({"Lua","Java","C#","C++"} , {__metatable="lock"} )
    print(getmetatable(tab))
    -- 使用__metatable可以保护元表,禁止用户访问元表中的成员或者修改元表。
    

    __index 元方法

    Lua 在查找一个表元素时的规则,是如下3个步骤:
    1.在表中查找,如果找到,返回该元素,找不到则继续。
    2.判断该表是否有元表,如果没有元表,返回 nil,有元表则继续。
    3.判断元表有没有 __index 方法,如果 __index 方法为 nil,则返回 nil;如果 __index 方法是一个表,则重复1、2、3;如果 __index 方法是一个函数,则返回该函数的返回值。

    mytable = {"Lua","Java","C#","C++"}
    
    --__index 当访问到一个表里不存在的索引的时候 起作用
    mymetatable = {
    __index = function (tab,key)
    	if(key>=10) then
    		return "Javascript"
    	end
    end
     }
    
    mytable =setmetatable(mytable,mymetatable)
    
    print(mytable)
    print(mytable[1])
    print(mytable[9]) 
    
    mytable = {"Lua","Java","C#","C++"}
    
    newtable = {seven="Javascript"}
    newtable[9]="C"
    
    mymetatable = {
    __index = newtable
     }
    
    mytable =setmetatable(mytable,mymetatable)
    
    print(mytable)
    print(mytable[1])
    print(mytable.seven)
    print(mytable[9]) 
    

    __newindex 元方法

    这个方法用来对表更新。当表设置了元方法 __newindex,在对新索引键赋值时,会调用元方法,而不进行赋值。而如果是对已存在的索引键,则会进行赋值,不调用元方法 __newindex。

    mytable = {"Lua","Java","C#","C++"}
    
    mymetatable = {
    __newindex = function(tab,key,value)
    	print("我们要修改的key为:"..key.." 把这个key值修改为:"..value)
    	rawset(tab,key,value)
    end
     }
    
    mytable =setmetatable(mytable,mymetatable)
    
    mytable[1]="C#"
    mytable[5]="Lua"
    
    print(mytable[1])
    print(mytable[5])
    
    mytable = {"Lua","Java","C#","C++"}
    
    newtable = {}
    
    mymetatable = {
    __newindex = newtable
    }
    
    mytable =setmetatable(mytable,mymetatable)
    
    mytable[1]="C#"
    mytable[5]="Lua"
    
    print(mytable[1])
    print(mytable[5])
    print(newtable[5])
    

    为表添加操作符

    相加操作,__add 操作符

    mytable = {"Lua","Java","C#","C++"} --普通表
    
    mymetatable = {
    __add = function(tab,newtab)
    	local mi = 0
    	for k,v in pairs(tab)do
    		if(k>mi) then
    			mi = k
    		end
    	end
    
    	for k,v in pairs(newtab) do
    		mi=mi+1
    		table.insert(tab,mi,v)
    	end
    	return tab
    end
    } --元表   元表扩展了普通表的行为
    
    mytable =setmetatable(mytable,mymetatable)
    newtable = {"PHP","Python"}
    
    v=mytable+newtable
    v2=newtable + mytable
    
    for k,v in pairs(v2) do
    	print(k,v)
    end
    

    __call元方法

    在表调用一个值时调用

    mytable = {"Lua","Java","C#","C++","ccdd"} 
    
    mymetatable = {
    __call = function (tab,arg1,arg2,arg3)
    	print(arg1,arg2,arg3)
    	return "MoGu"
    end,
    }
    
    mytable =setmetatable(mytable,mymetatable)
    
    v = mytable(123,34,453)
    
    print(v)
    

    __tostring 元方法

    用于修改表的输出行为,可以自定义表的输出内容
    示例一:

    mytable = {"Lua","Java","C#","C++","ccdd"} --普通表
    
    mymetatable = {
    __tostring = function (mytable)
    	local str = ""
    	for k,v in pairs(mytable) do
    		str = str..v..","
    	end
    	return str
    end
    }
    
    mytable =setmetatable(mytable,mymetatable)
    
    print(mytable)
    

    示例二:

    mytable = { 10, 20, 30} 
    
    mymetatable = {
    __tostring = function(mytable)
        sum = 0
        for k, v in pairs(mytable) do
            sum = sum + v
        end
        return "表所有元素的和为 " .. sum
      end
    }
    
    mytable =setmetatable(mytable,mymetatable)
    
    print(mytable)
    

    协同程序(coroutine)

    --定义协同函数coroutine.create
    --启动协同函数coroutine.resume
    --暂停协同函数coroutine.yield
    --继续运行 coroutine.resume (不需要传递参数)
    
    co=coroutine.create(
    	function (a,b)
    		print(a+b)
    		print(coroutine.status(co))
    		print(a+b)
    		print(coroutine.status(co))
    		print( coroutine.running() )
    		coroutine.yield(a*b,a/b)
    		print(a-b)
    
    		return a%b,a/b+1
    	end
    )
    print( coroutine.running() )
    print(coroutine.status(co))
    
    res1,res2,res3 = coroutine.resume(co,10,40)
    
    print(res1,res2,res3)
    
    print(coroutine.status(co))
    print("I'm here!")
    
    res1,res2,res3 = coroutine.resume(co)
    
    print(res1,res2,res3)
    
    print(coroutine.status(co))
    
    --第一个yield的参数作为第一个resume的返回值
    --第一个resume的参数作为协程的参数, 第二个resume的参数作为第一个yield的返回值
    
    
    function foo (a)
        print("foo 函数输出", a)
        return coroutine.yield(2 * a) -- 返回  2*a 的值
    end
     
    co = coroutine.create(function (a , b)
        print("第一次协同程序执行输出", a, b) -- co-body 1 10
        local r = foo(a + 1)
         
        print("第二次协同程序执行输出", r)
        local r, s = coroutine.yield(a + b, a - b)  -- a,b的值为第一次调用协同程序时传入
         
        print("第三次协同程序执行输出", r, s)
        return b, "结束协同程序"                   -- b的值为第二次调用协同程序时传入
    end)
            
    print("main", coroutine.resume(co, 1, 10)) -- true, 4
    print("--分割线----")
    print("main", coroutine.resume(co, "r")) -- true 11 -9
    print("---分割线---")
    print("main", coroutine.resume(co, "x", "y")) -- true 10 end
    print("---分割线---")
    print("main", coroutine.resume(co, "x", "y")) -- cannot resume dead coroutine
    print("---分割线---")
    

    Lua中文件的IO

    简单模式:拥有一个当前输入文件和一个当前输出文件,并且提供针对这些文件相关的操作。
    完全模式:使用外部的文件句柄来实现。它以一种面向对象的形式,将所有的文件操作定义为文件句柄的方法。

    打开文件操作语句如下:
    file = io.open (filename ,[ mode])

    模式诸如以下这些:
    r,以只读方式打开文件,该文件必须存在。
    w,打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
    a,以附加的方式打开只写文件。若文件不存在,建立该文件,如果存在,写入的数据会被加到文件尾,即原先的内容会保留。
    r+,以可读写方式打开文件,该文件必须存在。
    w+,打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
    a+,与a类似,但此文件可读可写
    b,二进制模式,如果文件是二进制文件,可以加上b
    +,号表示对文件既可以读也可以写

    简单模式

    -- 以只读方式打开文件
    file = io.open("data.lua", "r")
    
    -- 设置默认输入文件为 data.lua
    io.input(file)
    
    -- 输出文件第一行
    print(io.read())
    
    -- 关闭打开的文件
    io.close(file)
    
    -- 以附加的方式打开只写文件
    file = io.open("data.lua", "a")
    
    -- 设置默认输出文件为 data.lua
    io.output(file)
    
    -- 在文件最后一行添加 Lua 注释
    io.write("--  data.lua 文件末尾注释")
    
    -- 关闭打开的文件
    io.close(file)
    
    file = io.open("data1.txt","w")
    io.output(file)
    io.write("www.runoob.com1\n")
    io.write("www.runoob.com2")
    io.write("www.runoob.com3")
    io.write("www.runoob.com4")
    io.close(file)
    
    
    file = io.open("data1.txt","r")
    io.input(file)
    print(io.read(10)) --读取一行\
    print(io.read(10)) --读取一行\
    print(io.read(10)) --读取一行\
    print(io.read(10)) --读取一行\
    print(io.read(10)) --读取一行\
    io.close(file)
    

    完全模式

    file=io.open("data1.txt","r")
    print(file:read())
    print(file:read())
    file:close()
    
    file=io.open("data1.txt","a")
    file:write("www.runoob.com5")
    file:close()
    

    垃圾回收

    Lua 提供以下函数collectgarbage ([opt [, arg]])用来控制自动内存管理:

    collectgarbage(“collect”), 做一次完整的垃圾收集循环。通过参数 opt 它提供了一组不同的功能:
    collectgarbage(“count”),以 K 字节数为单位返回 Lua 使用的总内存数。 这个值有小数部分,所以只需要乘上 1024 就能得到 Lua 使用的准确字节数(除非溢出)。
    collectgarbage(“restart”),重启垃圾收集器的自动运行。
    collectgarbage(“setpause”),将 arg 设为收集器的 间歇率 (参见 §2.5)。 返回 间歇率 的前一个值。
    collectgarbage(“setstepmul”),返回 步进倍率 的前一个值。
    collectgarbage(“step”),单步运行垃圾收集器。 步长"大小"由 arg 控制。 传入 0 时,收集器步进(不可分割的)一步。 传入非 0 值, 收集器收集相当于 Lua 分配这些多(K 字节)内存的工作。 如果收集器结束一个循环将返回 true 。
    collectgarbage(“stop”),停止垃圾收集器的运行。 在调用重启前,收集器只会因显式的调用运行。

    mytable = {"apple", "orange", "banana"}
    
    print(collectgarbage("count"))
    
    mytable = nil
    
    print(collectgarbage("count"))
    print(collectgarbage("collect"))
    print(collectgarbage("count"))
    
    

    实现面向对象

    --对于一个对象来说  属性 方法
    
    person ={ name="MoGu",age=99 }
    
    person.eat = function ()
    	print(person.name.."在吃饭")
    end
    
    function person.eat()
    	print(person.name.."在吃饭")
    end
    
    person.eat()
    
    

    通过 “·” 来调用方法的时候,self 不会自动赋值,我们必须通过第一个参数来传递当前的 table。

    person ={ name="MoGu",age=99 }
    
    person.eat = function (self)
    	print(self.name.."在吃饭")
    end
    
    person.eat(person)
    
    a = person
    
    a.eat(a)
    
    

    通过 " : " 调用的时候,系统会自动传递当前的 table 给 self。

    person ={ name="MoGu",age=99 }
    
    function person:eat()
    	print(self.name.."在吃饭")
    end
    
    person:eat()
    
    a = person
    
    a:eat()
    
    

    new 新对象

    Person ={ name="MoGu",age=99 }
    
    function Person:eat()
    	print(self.name.."在吃饭")
    	print(self.name.."的年龄是"..self.age)
    end
    
    function Person:new(o)
    	local t = o or {}
    	--调用一个属性的时候,如果 t 中不存在,那么会在 __index 所指定的 table 中查找 setmetatable( t, { __index=self })
    	setmetatable(t,self)
    	self.__index=self
    
    	return t
    end
    
    Student = Person:new()
    Student.grade=1
    
    stu1 = Student:new()
    
    stu1:eat()
    print(stu1.grade)
    
    展开全文
  • 我们能用 lua 做什么

    万次阅读 2018-03-29 00:00:00
    女主宣言lua 是一个巴西人设计的小巧的脚本语言,它的设计目的是为了能够嵌入到应用程序中,从而为应用程序提供灵活的扩展和定制功能。今天我们邀请到 360 高级开发工程师李钢带我们快速入门 lue。本文最先发布于 ...
        

    640?wx_fmt=gif&wxfrom=5&wx_lazy=1

    女主宣言

    lua 是一个巴西人设计的小巧的脚本语言,它的设计目的是为了能够嵌入到应用程序中,从而为应用程序提供灵活的扩展和定制功能。今天我们邀请到 360 高级开发工程师李钢带我们快速入门 lue。本文最先发布于 opsdev,转载已获取作者授权。 

    PS:丰富的一线技术、多元化的表现形式,尽在“HULK一线技术杂谈”,点关注哦!

    前言

    作为web开发工程师,我们平时主要使用的开发语言是php。这个语言提供了对html模版的强大的处理能力,也提供了十分丰富的函数库及扩展,非常的适合web开发使用。那么lua是如何进入到我们的视线中的呢?在这里我先说下我在开发一个web产品时,会优先考虑的几个问题:


    1. 如何保证服务的稳定性,即如何防止白屏、50x错误的发生。

    2. 如何提高页面的响应速度,即让用户感觉页面打开足够快。

    3. 那么在用php解决这几个问题时,是否够用呢?


    答案在我看来是否定的,为什么这么说呢?请听我分别道来:


    1

    php在处理服务稳定性时的不足

    先简单说下由php导致的服务异常原因:


    1. php语法错误、运行时的异常都会导致500错误,这在用户端浏览器就会显示出白屏。

    2. 在使用nginx + php-cgi这种组合提供动态web服务时,当后台cgi进程挂掉或数量不够用时,即会产生502错误;当php执行时遭遇阻塞(如连db时,db压力过大),而在nginx中配置的超时时间到达后,通常会产生504错误。


    这几种异常本身都是由于php导致的,当然不能靠php去解决。


    webserver如nginx提供了如error_page这种用于处理当服务产生异常时的后续处理机制,为了不让用户看到白屏或错误页面,我们可以定时对正常服务时的页面做一个快照,当遇到服务异常时,就给用户这个历史快照看。


    但这样做也有个局限性:当你提供服务的页面很多时,又或是需要根据请求的参数做一些逻辑上的处理时,显然就很难做到了。


    你也许会说,我可以写nginx配置,让它分析请求参数,再做相应的逻辑处理。但是这样做的话,想想看你的nginx配置会有多么的复杂,多么的难以维护,而且就算你这样做,也不能解决所有的问题。比如说我有个接口要输出json字符串,或是其它别的格式,你总不能说我再去写个nginx扩展让它支持json吧。


    所以,在提高服务的稳定性方面,我们的需求是:


    1. 能用到webserver提供的错误处理机制。

    2. 能方便的处理请求参数,做需要的逻辑处理。


    2

    php在提高用户响应速度方面的不足

    php是一个阻塞式顺序执行的脚本语言,虽然支持多进程执行,但这种模式并不适合使用在并发量很高的web服务中。


    想像如果一个请求的处理过程中,你需要调用到多处外部资源或服务(db、rest接口),那么你的处理速度就要依赖于这些外部服务,而且是一个一个顺序处理的,它们越多,处理就越慢。


    php的multi_curl可以用来并发请求这些外部的rest服务,但这样做的话,依旧需要等全部的请求都处理完成,才能返回给用户。换句话说,如果某个外部服务很慢,那么用户看到页面打开依旧会很慢。


    也可以选择把页面分块,让慢的部分用js异步请求加载。但这样做的话,会增加服务器的访问量,每增加一块,访问量会增大一倍。


    所以,在提高页面的响应速度方面,我们的需求是:


    1. 耗时慢的服务能够做到异步加载,服务端每完成一部分的计算,就让页面展示这部分。

    2. 不能过大的增加服务器的压力。


    3

    nginx-lua模块

    最终,我们找到了nginx-lua?模块。这个模块会在每个nginx的worker_process中启动一个lua解释器,在nginx处理http请求的11个阶段中,你可以在其中的多个阶段用lua代码处理请求。


    这二者的结合,给我们的web开发带来了新的思路。下面我就来说下导航目前是如何使用它来解决问题的。


    4

    解决服务稳定性

    这里的思路很简单,我们会在error_page指令被执行后,用lua代码来接受参数,处理逻辑部分,最终会返回前端和用php处理看起来一致的内容。部分代码如下:


    nginx_conf:

    640?wx_fmt=jpeg

    这里大家看到,当请求出现50x错误时,会跳到location jump_to_error_page_api中,在这里面,content_by_lua_file指令会在content处理阶段启动指定好的lua脚本(这里是error_page_api.lua)来处理请求。我们再看下lua脚本中都做了什么:


    lua example:

    640?wx_fmt=jpeg

    这里大家可以看到,我们可以在lua脚本中接受请求参数,做和php一样的逻辑,最终输出前端需要的正确的内容。


    目前这套机制我们已经用在我们这边的一个重要用户页面上,目前都没有收到用户反馈说页面打不开,出现错误页这种,效果很是明显。


    5

    提高用户页面的响应速度

    上面提到的解决响应速度的几个需求,我们的思路是引入bigpipe的处理机制。关于bigpipe本文不做讲解,大家可以自行google。这个项目目前尚处于实验阶段,但我们已经实现了一个简单的demo:


    nginx_conf:

    640?wx_fmt=jpeg

    这里指定请求index.php会用bigpipe_index.lua处理。


    lua example:

    640?wx_fmt=jpeg

    这里在处理请求时,大致逻辑如下:


    1. 首先会先吐出首屏html部分及部分html框架代码。

    2. 接下来会启动3个lua协程,在nginx-lua这个模块的调度下以异步非阻塞的模式并发的来处理3个外部请求。

    3. 这3个外部请求各自的延时不同,但是任何一部分处理完成,都会直接返回给前端用于展示。


    通过这种方式,用户的页面响应速度得到了明显的提高,体验更好。


    6

    结束语

    正如lua官方给出的定义所说,lua很小巧,非常的适合嵌入已有的应用程序中,从而补足现有系统的一些缺憾,并扩展出新的功能。对nginx-lua模块的使用,笔者也还在研究中,但我相信更好的使用它,能为我们现有的web开发打开一扇新的窗户,理解更深层次的知识。

    参考资料:

        

    [1] https://www.lua.org/

    [2] https://github.com/openresty/lua-nginx-module

    HULK一线技术杂谈

    由360云平台团队打造的技术分享公众号,内容涉及云计算数据库大数据监控泛前端自动化测试等众多技术领域,通过夯实的技术积累和丰富的一线实战经验,为你带来最有料的技术分享

    640?wx_fmt=gif
    展开全文
  • Lua语言从入门到精通

    万人学习 2016-09-20 13:10:47
    深入浅出Lua学习
  • 1.如何编译lua 2.C++ 中调用lua函数 3.lua中如何调用C++函数 4.深入的介绍lua栈(lua的灵魂) 5.lua闭包和上值的使用 6.lua元表的使用(lua的精髓) 7.实现导出C++类给lua 8.实现自动化导出类给lua 9.导出OpenGL...
  • lua入门

    千次阅读 2019-02-04 23:40:52
    redis2.6以后可以在redis 中使用lua语言。 1、用lua的好处: 1)一个脚本包含多个操作,减少访问次数从而减少网络开销 2)原子操作 redis 对lua脚本是原子化执行方案 3)复用性 复用 lua脚本的逻辑 2、lua脚本...

    redis2.6以后可以在redis 中使用lua语言。
    1、用lua的好处:
    1)一个脚本包含多个操作,减少访问次数从而减少网络开销
    2)原子操作 redis 对lua脚本是原子化执行方案
    3)复用性 复用 lua脚本的逻辑
    2、lua脚本安装:
    1)下载安装包 并解压

     tar-zvxf lua-5.3.5.tar.gz
    

    2)执行 make linux 编译
    编译过程报错 lua.c:82:31: 致命错误:readline/readline.h:没有那个文件或目录
    百度一下得知,需要安装依赖
    执行 如下命令安装依赖:

    yum install libtermcap-devel ncurses-devel libevent-devel readline-devel
    
    

    重新解压编译

    [root@192 lua-5.3.5]# make linux test
    cd src && make linux
    make[1]: 进入目录“/usr/apps/lua/lua-5.3.5/src”
    make all SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline"
    make[2]: 进入目录“/usr/apps/lua/lua-5.3.5/src”
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o lapi.o lapi.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o lcode.o lcode.c
    

    然后 运行 lua 就启动进入了 lua 如下:

    [root@192 ~]# lua
    Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
    > 
    

    3、初步使用
    lua特点 动态类型的语言,和js类似
    变量 分为 全局变量 和局部变量

    单行注释 –
    多行注释 --[[ ]]

    全局变量 a=1
    局部变量 local b=1
    逻辑表达式 ±*/
    测试代码如下 编辑脚本 luatest :
    vi testlua 输入内容 (lua testlua 执行脚本)

    a=1
    local b=2
    print(a+b)
    

    执行 lua luatest 结果
    在这里插入图片描述

    关系运算符
    a==b 比较两个值是否相等
    ~= 比较两个值是否不等

    a=1
    local b=2
    --print(a+b)
    print (a==b)
    print (a~=b)
    print(a=='1')
    

    执行 lua luatest 结果
    在这里插入图片描述

    逻辑运算符
    and
    or
    not

    测试脚本:

    true
    false
    [root@192 lua-5.3.5]# vi luatest
    print((a==b)and(a==1
    a=1
    local b=2
    --[[print(a+b)
    print (a==b)
    print (a~=b)
    print(a=='1')
    ]]
    print((a==b)and(a==1) )
    print((a==b)or(a==1) )
    print(not(a==b))
    

    执行 lua luatest 结果
    在这里插入图片描述

    字符串 操作
    … 拼接 a…b 拼接字符串 a和b 同 java 的a+b
    #计算字符串的长度 #a 字符串a 的长度
    测试代码

    str1='hello'
    str2='world'
    print(str1..str2)
    print(#str1)
    

    在这里插入图片描述

    条件判断 如下
    a=1
    if( a == 1) then
    print(‘a=1’)
    elseif( b == 2) then
    print(‘b=2’)
    else
    print(‘111’)
    end

    执行结果:
    a=1

    循环
    a=1
    while(a<10) do
    print(a)
    a=a+1
    end
    测试结果:
    在这里插入图片描述

    for i=1,5 do
    print(i)
    end
    测试
    在这里插入图片描述

    遍历数组

    local arr={‘a’,‘b’,‘c’}
    for i,v in ipairs(arr) do
    print(i…’=’…v)
    end
    [root@192 lua-5.3.5]# lua luatest
    1=a
    2=b
    3=c
    [root@192 lua-5.3.5]#

    测试结果如下

    local function add(a,b)
    return a+b;
    end
    print(add(1,2))
    "luatest" 46L, 474C written
    [root@192 lua-5.3.5]# lua luatest 
    3
    

    其他内置操作:Sting 操作字符串 Table 操作数组

    4、redis 整合 lua

    lua 提供了redis 的操作 如:redis.call(‘set‘,‘name’,‘zhang’)
    但是直接运行该段脚本提示错误 如下

    > redis.call('set','name','zhang');
    stdin:1: attempt to index global 'redis' (a nil value)
    stack traceback:
            stdin:1: in main chunk 
            [C]:
    

    原因是直接在lua环境中运行该脚本,没有依赖的redis引擎。所以报错。
    因为redis中提供了这个引擎,所以在redis中运行该段脚本就没有这个问题了。
    在redis-cli 中运行该段脚本的方式: eval “脚本” keynumbers key… arg…[参数(没有参数写0)]
    如下:

    127.0.0.1:6379> eval "redis.call('set','name','zhang')" 0
    (nil)
    127.0.0.1:6379> get name
    "zhang"
    127.0.0.1:6379> 
    

    有参数的测试:
    通过 1(传入几个键) ‘name’ ‘lisi’ 出入参数
    在脚本中 通过KEYS[1] 和 ARGV[1] 获取使用参数如下(下标从1开始):

    127.0.0.1:6379> eval "return redis.call('set',KEYS[1],ARGV[1])" 1 'name' 'lisi'
    OK
    127.0.0.1:6379> get name
    "lisi"
    

    5、lua实现访问ip频率限制
    编写脚本

    local num = redis.call('incr',KEYS[1])
    if (tonumber(num)==1) then
        redis.call('expire',KEYS[1],ARGV[1])
        return 1
    elseif (tonumber(num)>tonumber(ARGV[2])) then
        return 0
    else
        return 1
    end
    

    然后执行脚本 10秒内 第11次返回为0 10秒后返回为1

    [root@192 bin]# ./redis-cli --eval "iplimitlua.lua" ip1 , 10 , 10
    (integer) 1
    [root@192 bin]# ./redis-cli --eval "iplimitlua.lua" ip1 , 10  10
    (integer) 1
    [root@192 bin]# ./redis-cli --eval "iplimitlua.lua" ip1 , 10  10
    (integer) 1
    [root@192 bin]# ./redis-cli --eval "iplimitlua.lua" ip1 , 10  10
    (integer) 1
    [root@192 bin]# ./redis-cli --eval "iplimitlua.lua" ip1 , 10  10
    (integer) 1
    [root@192 bin]# ./redis-cli --eval "iplimitlua.lua" ip1 , 10  10
    (integer) 1
    [root@192 bin]# ./redis-cli --eval "iplimitlua.lua" ip1 , 10  10
    (integer) 1
    [root@192 bin]# ./redis-cli --eval "iplimitlua.lua" ip1 , 10  10
    (integer) 1
    [root@192 bin]# ./redis-cli --eval "iplimitlua.lua" ip1 , 10  10
    (integer) 1
    [root@192 bin]# ./redis-cli --eval "iplimitlua.lua" ip1 , 10  10
    (integer) 1
    [root@192 bin]# ./redis-cli --eval "iplimitlua.lua" ip1 , 10  10
    (integer) 1
    [root@192 bin]# ./redis-cli --eval "iplimitlua.lua" ip1 , 10  10
    (integer) 0
    
    

    遇到的问题:
    执行lua脚本时 要 ./redis-cli --eval “iplimitlua.lua” ip1 , 10 10 这样来执行 (ip1 为ip地址key ,10 10 表示 10 秒内访问不能大于10次 并且逗号前后要有空格)
    而不能 先执行 ./redis-cli
    然后执行 -eval “iplimitlua.lua” ip1 , 10 10 这样会报错

    6、lua脚本原子性验证
    一个redis-cli 中执行一个死循环 如下:

    [root@192 bin]# ./redis-cli
    127.0.0.1:6379> eval "while true do print(1) end" 0
    

    另一个客户端也链接 redis 执行redis操作 提示 redis is buzy .不能执行任何操作。

    [root@192 bin]# ./redis-cli
    127.0.0.1:6379> get name
    (error) BUSY Redis is busy running a script. You can only call SCRIPT KILL or SHUTDOWN NOSAVE.
    

    只有杀死redis服务重启后才能正常访问redis

    7、jedis 执行lua脚本
    两种方式 一种是直接执行脚本
    一种是 将脚本缓存在服务端,以摘要的方式执行,避免每次都传递完整脚本到服务端。具体脚本如下:

    
    
    public class TestLUA {
    	public static String lua="local num = redis.call('incr',KEYS[1]) "+
    							"if (tonumber(num)==1) then "+
    							"    redis.call('expire',KEYS[1],ARGV[1]) "+
    							"    return 1 "+
    							"elseif (tonumber(num)>tonumber(ARGV[2])) then "+
    							"    return 0 "+
    							"else "+
    							"    return 1 "+ 
    							"end";
    	public static String sha =null;
    	public static String loadScript() throws Exception{
    		//
    		Jedis jedis=RedisManager.getJedis();
    		//将脚本缓存到服务端并返回摘要信息
    		String sha = jedis.scriptLoad(lua);
    		System.out.println("sha===>"+sha);
    		return sha;
    	}
    	
    	public static Object testLua1() throws Exception{
    		if(null==sha){
    			System.out.println("加载脚本");
    			sha=loadScript();
    		}
    		
    		Jedis jedis=RedisManager.getJedis();
    		//String sha = jedis.scriptLoad(lua);
    		List<String> keys = new ArrayList<String>();
    		keys.add("ip:limit:127.0.0.1");
    		
    		List<String> args = new ArrayList<String>();
    		args.add("30");
    		args.add("10");
    		//以摘要方式执行脚本
    		return jedis.eval(sha, keys, args); 
    		
    	}
    	
    	public static Object testLua2() throws Exception{
    		
    		Jedis jedis=RedisManager.getJedis();
    		List<String> keys = new ArrayList<String>();
    		keys.add("ip:limit:127.0.0.1");
    		
    		List<String> args = new ArrayList<String>();
    		args.add("30");
    		args.add("10");
    		
    		return jedis.eval(lua, keys, args); //这样每次都传递脚本到服务端增加网络消耗
    		
    	}
    	
    	public static void main(String[] args) throws Exception {
    		for(int i=0;i<13;i++){
    			System.out.println(testLua1());
    			//System.out.println(testLua2());
    
    		}
    		
    	}
    
    }
    
    
    展开全文
  • lua 中文版

    2018-08-25 16:26:34
    lua中文开发,清晰版,lua与nginx,lua中文开发,清晰版,
  • 现在最新版本lualua-5.2.3。
  • LUA快速使用指南

    千次阅读 2018-05-16 20:35:38
    Lua在葡萄牙语中是月亮的意思,是一个有效的轻量级的可嵌入式脚本语言。它支持面向对象和面向过程的编程方式。从1993年被开发出来至今已经有25岁的高龄了。老当益壮,不坠青云之志,Lua仍然非常地活跃,比如深度学习...

    这里写图片描述
    Lua在葡萄牙语中是月亮的意思,是一个有效的轻量级的可嵌入式脚本语言。它支持面向对象和面向过程的编程方式。从1993年被开发出来至今已经有25岁的高龄了。老当益壮,不坠青云之志,Lua仍然非常地活跃,比如深度学习的开源框架Torch就使用Lua和C作为开发的主要语言。

    曾经在游戏开发者杂志的编程工具分类获得2011年的Front Line Award奖项,Lua得到了很高的评价:Lua成为了一们非常流行的编程语言,在游戏领域尤其如此。部分原因是由于它的速度和易用性,开发者可以将Lua嵌入到游戏引擎中。同时,Lua还有很高的可扩展性。另外在源码文件以及运行所需的内存使用量方面都是相对较小。游戏开发者杂志对Lua进行了不遗余力的赞美,详细可以参看如下链接:

    URL http://www.gamasutra.com/view/news/129084/Announcing_Game_Developer_magazines_2011_Front_Line_Award_winners.php

    基本信息

    项目 说明
    官方网站 http://www.lua.org/
    开源/闭源 开源
    License类别 MIT License
    代码管理地址 http://www.lua.org/ftp/
    开发语言 C
    更新频度 平均每年数次更新
    提供者 Waldemar, Roberto, Luiz
    支持平台 使用ANSI C开发的Lua可以支持任何能够运行ANSI C的平台,基本常见的OS都可以从源码进行编译和安装
    当前版本 5.3.4(2017/01/12)

    Lua的开发者

    这里写图片描述

    版本演进

    这里写图片描述

    功能特色

    相较于其他脚本余元,Lua有显著的自身特色:

    快速

    官方号称Lua在性能方面有较好的名声,而其他编程语言也有强烈的愿望能够”as fast as Lua”, 据称在一些对标中Lua都在交互式的脚本语言中是最快的。

    可移植

    由于Lua使用了ANSI C的开发,而几乎所有的操作系统对ANSI C提供支持,所以Lua可以运行在Unix/Windows/IBM大型机/诸如Android,iOS,Symbian等移动设备上。

    可嵌入

    Lua提供简单而强大的API方便集成到其他语言中,可以使用其他语言写的库对Lua进行扩展,同时也可以使用其他语言和Lua一起对应用程序进行更好地扩展。Lua不仅仅支持C/C++,同时对Java/C#/Perl/Ruby/Smalltalk/Ada/Fortran/Erlang等进行结合使用。

    强大且简单

    在特性开发上Lua秉承所谓的meta-mechanisms的重要设计理念,通过这种方式实现了很多重要的功能,比如Lua虽然不是纯粹的面向对象语言,但是通过meta-mechanisms机制可以实现类和继承。

    small

    最新的5.3.4的tar包,压缩之后只有297K,而解压后也仅有1.1M。Lua的源码仅有24000行左右,在64位的Linux下,Lua的解释器和标准库也仅有几百K的大小。

    免费

    Lua采用了对商业非常友好的MIT License,可用于商业目的,你所需要的只是下载下来。

    安装部署

    在本文中使用源码编译的方式进行Lua的安装

    事前准备:yum install -y gcc readline-devel

    使用gcc是为了编译,而readline-devel则是因为在Lua的源码中使用了相关模块

    [root@devops lua-5.3.4]# find . -type f |xargs grep readline.h
    ./src/lua.c:#include <readline/readline.h>
    ./src/lua.c:#include <readline/history.h>
    [root@devops lua-5.3.4]# 

    具体5.3.4的源码安装命令如下:

    curl -R -O http://www.lua.org/ftp/lua-5.3.4.tar.gz
    tar zxf lua-5.3.4.tar.gz
    cd lua-5.3.4
    make linux test

    安装日志:

    [root@devops ~]# curl -R -O http://www.lua.org/ftp/lua-5.3.4.tar.gz
    ...省略
    [root@devops ~]# tar zxf lua-5.3.4.tar.gz
    [root@devops ~]# cd lua-5.3.4
    [root@devops lua-5.3.4]# make linux test
    cd src && make linux
    make[1]: Entering directory `/root/lua-5.3.4/src'
    make all SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline"
    make[2]: Entering directory `/root/lua-5.3.4/src'
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o lapi.o lapi.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o lcode.o lcode.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o lctype.o lctype.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o ldebug.o ldebug.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o ldo.o ldo.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o ldump.o ldump.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o lfunc.o lfunc.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o lgc.o lgc.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o llex.o llex.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o lmem.o lmem.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o lobject.o lobject.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o lopcodes.o lopcodes.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o lparser.o lparser.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o lstate.o lstate.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o lstring.o lstring.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o ltable.o ltable.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o ltm.o ltm.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o lundump.o lundump.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o lvm.o lvm.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o lzio.o lzio.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o lauxlib.o lauxlib.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o lbaselib.o lbaselib.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o lbitlib.o lbitlib.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o lcorolib.o lcorolib.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o ldblib.o ldblib.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o liolib.o liolib.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o lmathlib.o lmathlib.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o loslib.o loslib.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o lstrlib.o lstrlib.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o ltablib.o ltablib.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o lutf8lib.o lutf8lib.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o loadlib.o loadlib.c
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o linit.o linit.c
    ar rcu liblua.a lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o lundump.o lvm.o lzio.o lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o lmathlib.o loslib.o lstrlib.o ltablib.o lutf8lib.o loadlib.o linit.o 
    ranlib liblua.a
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o lua.o lua.c
    gcc -std=gnu99 -o lua   lua.o liblua.a -lm -Wl,-E -ldl -lreadline 
    gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX    -c -o luac.o luac.c
    gcc -std=gnu99 -o luac   luac.o liblua.a -lm -Wl,-E -ldl -lreadline 
    make[2]: Leaving directory `/root/lua-5.3.4/src'
    make[1]: Leaving directory `/root/lua-5.3.4/src'
    src/lua -v
    Lua 5.3.4  Copyright (C) 1994-2017 Lua.org, PUC-Rio
    [root@devops lua-5.3.4]#

    在结果的最后已经看到了Lua 5.3.4的信息

    安装结果确认

    可以看到Lua的Size像它宣称的一样,非常之小,仅仅248K,从3.5寸软盘和DOS时代走过来的应用程序自然对大小有特殊的注意。

    [root@devops lua-5.3.4]# du -k src/lua
    248 src/lua
    [root@devops lua-5.3.4]#

    确认版本信息

    [root@devops lua-5.3.4]# src/lua -v
    Lua 5.3.4  Copyright (C) 1994-2017 Lua.org, PUC-Rio
    [root@devops lua-5.3.4]#

    当前的机器已经安装了lua,版本为5.1.4, 将其更新为刚刚编译的5.3.4版本,仅仅需要将可执行文件覆盖即可

    [root@devops lua-5.3.4]# cp src/lua /usr/bin/
    cp: overwrite ‘/usr/bin/lua’? y
    [root@devops lua-5.3.4]# which lua
    /usr/bin/lua
    [root@devops lua-5.3.4]# lua -v
    Lua 5.3.4  Copyright (C) 1994-2017 Lua.org, PUC-Rio
    [root@devops lua-5.3.4]# 

    C语言时代的软件,对细节还是把握的很好的

    [root@devops lua-5.3.4]# ldd /usr/bin/lua
        linux-vdso.so.1 =>  (0x00007fff306e5000)
        libm.so.6 => /lib64/libm.so.6 (0x00007fda590e4000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007fda58ee0000)
        libreadline.so.6 => /lib64/libreadline.so.6 (0x00007fda58c99000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fda588d6000)
        /lib64/ld-linux-x86-64.so.2 (0x0000562cd2f9d000)
        libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007fda586ac000)
    [root@devops lua-5.3.4]# 

    使用简例

    第一个Hello World:交互方式

    接下来使用lua来进行第一个Hello World的使用

    [root@devops lua-5.3.4]# lua -i
    Lua 5.3.4  Copyright (C) 1994-2017 Lua.org, PUC-Rio
    > print("Hello World")
    Hello World
    > 

    也可以这样:

    > print "Hello World"
    Hello World
    > 

    也可以这样:

    > print 'Hello World'
    Hello World
    > 

    还可以这样:

    > print('Hello World')
    Hello World
    > 

    但是不能这样:

    > print "Hello world'
    >> 
    stdin:1: unfinished string near '"Hello world''
    > 

    使用Ctrl + d可以退出交互模式

    第一个Hello World程序:文件方式

    除了交互式,也可以使用文件方式保存可执行的代码,然后通过lua进行执行,比如代码信息如下

    [root@devops ~]# cat Hello.lua 
    print("Hello World")
    print('Hello World')
    print "Hello World"
    print 'Hello World'
    [root@devops ~]# 

    执行Hello.lua

    [root@devops ~]# lua Hello.lua 
    Hello World
    Hello World
    Hello World
    Hello World
    [root@devops ~]#

    也可以使用如下方式,在文件中指定解析的程序并赋予可执行权限并执行

    [root@devops ~]# cat Hello.lua 
    #!/usr/bin/lua
    
    print("Hello World")
    print('Hello World')
    print "Hello World"
    print 'Hello World'
    [root@devops ~]# chmod +x Hello.lua 
    [root@devops ~]# ./Hello.lua 
    Hello World
    Hello World
    Hello World
    Hello World
    [root@devops ~]#

    基本语法

    注释

    单行注释

    使用两个减号作为单行注释: –注释内容

    多行注释

    使用如下方式进行多行注释

    --[[
    注释内容
    --]]

    具体例子

    [root@devops ~]# cat Hello.lua 
    #!/usr/bin/lua
    
    --single line comment
    print("Hello World") --single line comment
    print('Hello World')
    
    --[[
    multiple lines comment
    multiple lines comment
    multiple lines comment
    --]]
    print "Hello World"
    print 'Hello World'
    [root@devops ~]#

    关键字

    Lua具有如下关键字

    • if
    • elseif
    • else
    • then
    • end
    • for
    • while
    • do
    • until
    • break
    • return
    • rue
    • false
    • nil
    • and
    • not
    • or
    • in
    • function
    • local
    • repeat

    八种基本数据类型

    Lua中变量无需进行类型定义,默认情况下变量生命域为全局,在Lua中,全局变量不需要事先声明,赋值后即创建,访问没有初始化的变量也不会出错,只是会得到nil,而将一个变量赋值成nil时可以相当于删除了此变量。nil为Lua的基本数据类型的一种,Lua有如下八种数据类型

    类型 说明
    nil 表示无效值
    boolean 布尔值:true或false
    string 字符串:使用单引号或者双引号来表示
    number 数字型:双精度类型
    function 函数类型
    thread Lua中使用coroutine实现类似线程的功能
    table 关联数组
    userdata 用户自定义类型

    变量生命域

    Lua中默认情况变量生命周期为全局,可以通过local来指定变量生命域

    [root@devops ~]# cat lua1.lua 
    #!/usr/bin/lua
    
    var_global='liumiaocn'
    
    function sayHello()
      local var_local='hello'
      print("In function:",var_local)
    end
    
    print (var_local,var_global)
    sayHello()
    [root@devops ~]#

    可以看到local修饰的变量在函数之外无法取到值

    [root@devops ~]# ./lua1.lua 
    nil liumiaocn
    In function:    hello
    [root@devops ~]# 

    逻辑控制

    写法非常接近BSHELL,将fi换成end即可

    [root@devops ~]# cat lua2.lua 
    #!/usr/bin/lua
    
    if false then
      print "false branch "
    elseif nil then
      print "nil branch "
    else
      print 'false and nil will not be performed'
    end
    [root@devops ~]#

    执行确认

    [root@devops ~]# chmod +x lua2.lua 
    [root@devops ~]# 
    [root@devops ~]# ./lua2.lua 
    false and nil will not be performed
    [root@devops ~]# 

    循环控制

    Lua中的循环有三种:for/while/repeat…until。Lua支持循环的嵌套。
    for循环

    [root@devops ~]# cat lua3.lua 
    #!/usr/bin/lua
    
    print "for loop :"
    
    for i=1,3,1
    do
      print(i)
    end
    
    print 'default increment'
    for i=1,2
    do
      print(i)
    end
    [root@devops ~]# 
    [root@devops ~]# chmod +x lua3.lua 
    [root@devops ~]# ./lua3.lua 
    for loop :
    1
    2
    3
    default increment
    1
    2
    [root@devops ~]# 

    while循环

    [root@devops ~]# cat lua4.lua 
    #!/usr/bin/lua
    
    i=1
    
    print "while loop"
    while(i<=3)
    do
      print(i)
      i=i+1
    end
    [root@devops ~]# chmod +x lua4.lua 
    [root@devops ~]# ./lua4.lua 
    while loop
    1
    2
    3
    [root@devops ~]#

    repeat…until循环

    [root@devops ~]# cat lua5.lua 
    #!/usr/bin/lua
    
    i=1
    
    print "repeat...unitl loop"
    repeat
      print(i)
      i=i+1
    until(i>3)
    [root@devops ~]# chmod +x lua5.lua 
    [root@devops ~]# ./lua5.lua 
    repeat...unitl loop
    1
    2
    3
    [root@devops ~]#

    文件读写

    Lua还提供很多其他的功能,诸如文件读写,你会发现和C语言非常相像,当然简化很多。

    [root@devops ~]# cat lua6.lua
    #!/usr/bin/lua
    
    fileStream=io.open("test-lua.txt","a")
    io.output(fileStream)
    io.write("Hello Lua\n")
    io.write("Greetings from Liumiao\n")
    io.close(fileStream)
    [root@devops ~]# chmod +x lua6.lua 
    [root@devops ~]# ./lua6.lua 
    [root@devops ~]# 
    [root@devops ~]# cat test-lua.txt 
    Hello Lua
    Greetings from Liumiao
    [root@devops ~]# 

    总结

    在这篇文章中,我们了解了Lua的一些特性以及基本数据结构和常见的一些控制的写法,基本可以快速上手。至于更详细的使用方法可以参看如下文档:

    使用文档 http://www.lua.org/manual/5.3/
    展开全文
  • lua下载和基本使用

    千次阅读 2018-09-01 11:11:55
    1、首先去lua官网下载软件 网页链接 http://www.lua.org/ 2、安装之后如果电脑桌面的快捷键不能打开 就去根目录找到 .exe可执行文件 例如我的安装目录 3、双击SciTE.exe界面是这样的 4、当我们写...
  • Windows下Lua安装环境配置教程

    千次阅读 2019-07-03 14:44:31
    首先是进入lua官网:https://www.lua.org/ 点击GetStart 点击LuaDist 进入下载界面 点击Windows86进行下载: 下载好之后,进行解压就行: 解压之后,在Windows环境变量Path添加解压文件的bin目录: ...
  • lua 中 . 和 : 的区别

    万次阅读 2019-01-05 16:27:27
    lua 中 . 和 : 的区别 首先在lua中使用“:”定义的函数会自动传入一个名为self的变量,这个变量是隐含的,self同c++中的this一样,表示当前对象的指针:而“.”定义的函数中没有self。 function class:func2( ) ...
  • Python、Lua语言的优缺点

    千次阅读 2018-06-27 22:22:08
    Python的优点: 1.Python比其它语言有更多扩展模块。...5.很多工具可以用于Python,但难以找到适用于Lua和Ruby的。 6… Python的不足: 1.因为栈上的任何东西都是对象,所以Python有时候会慢得难以忍受。 2…....
  • 使用lua脚本开发wow插件入门篇

    万次阅读 多人点赞 2019-09-25 10:59:01
    相信有接触过游戏开发的童鞋都知道lua这个脚本语言,Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。关于lua的简介...
  • Lua语言的入门以及Redis、Redisson、Spring-data-redis调用lua脚本示例
  • lua脚本的加密和解密(GG游戏脚本)

    万次阅读 多人点赞 2018-05-10 10:44:38
    他们这种外挂很多都是用GG修改器修改本地代码然后实现游戏里的透视变色自瞄之类的变态功能,有GG不行还得有脚本,这里的脚本就是LUA脚本.这种脚本我就不做多解释了自己可以去百度一下!意思就是你只要把这脚本放到GG上...
  • Redis缓存技术学习系列之Lua脚本

    千次阅读 2017-09-27 22:32:49
    想起来大概有一个月没有更新博客啦。或许是因为这中间发生了太多的事情,想来人生原本就充满曲折和变数。在微信群里得知家中舅爷去世的消息,突然意识到时间早已摧毁你我的一切。那个曾经同你有千丝万缕联系的人,会...
  • 1、LUA是一门脚本语言 ①、什么是脚本脚本语言又被称为扩建的语言,或者动态语言,是一种编程 语言,用来控制软件应用程序,脚本通常以文本(如ASCII)保存,只在 被调用时进行解释或编译 ②、 脚本语言的执行 ...
  • 第一次写Lua脚本,并通过springboot的redisTemplate调用脚本,进行脚本与应用的交互。不熟悉真的折腾了好久,现在总结一下学习过程: 第一次写完lua时,想到的就是如何在应用调用脚本的时候,去调试脚本。在网上海...
  • redis执行lua脚本

    千次阅读 2019-03-22 17:44:55
    从redis 2.6.0版本开始,redis内置了Lua解释器,并提供了eval命令来解析Lua脚本求值。 1. 语法格式 语法: eval script numkeys keys args 参数: eval — redis提供解析lua脚本的命令 script — lua脚本 ...
  • Lua脚本代码实例

    2013-02-24 21:34:04
    项目实现的Lua脚本代码,有需要的朋友可以参考

空空如也

1 2 3 4 5 ... 20
收藏数 168,649
精华内容 67,459
关键字:

lua