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中文开发,清晰版,
  • Lua的一些Demo

    2018-11-14 18:29:05
    排列大小 test = {2,453,223,76,888,90,323,4345,5,66,112,231} i=1 j=1 while i &lt;(#test) do --外循环,需要把所有数字都比较一次,共#test-1次 while j&lt;=(#test-i) do --内循环,每比较一个数字后...

    排列大小

    test = {2,453,223,76,888,90,323,4345,5,66,112,231}
    
    i=1
    j=1
    while i <(#test) do    --外循环,需要把所有数字都比较一次,共#test-1次
        while j<=(#test-i) do   --内循环,每比较一个数字后,下一个都会少一次
            if test[j] < test[j+1]then  --比较大小
                test[j],test[j+1]=test[j+1],test[j]   --替换位置
            end
            j=j+1
        end
        j=1
        i=i+1
    end
    
    
    for k,v in pairs(test) do  --遍历出来
        print(v)
    
    end
    

    找出100被7整出的数

    i=7
    while i<=100 do
    if i%7==0 then
        print(i)
    end
    i=i+1
    
    end
    
    

    乘法口诀

    --第一种写法
    function chengfa1()
        for a = 1, 9 do
            local c = ""
            for b = 1, 9 do
                if a>=b then
                    c = c..b.."x"..a.."="..a*b.."\t"
                end
                end
            print(c)
    
        end
    end
    
    
    --第二种写法
    function chengfa2()  --创建函数
        for a = 1,9 do    --定义一个循环1到9
            local s = ""  ---- 定义局部变量s
            for b=1,9 do
                if a>=b then
                    s = s..string.format( "%dX%d=%d\t",a,b,a*b )--..用来连接,
                end
            end
            print(s)
        end
    
    end
    
    
    --chengfa1()
    chengfa2()
    
    

    在这里插入图片描述

    展开全文
  • VS2017编译lua源码指北

    2020-11-12 21:55:14
    一、下载lua源码并解压二、打开Visual Studio 2017创建一个空的项目三、导入资源文件四、移除lua.c和luac.c文件(可选操作)五、添加预处理宏Q1: 这里我们为什么要添加预处理宏呢?Q2: 那么 __declspec(dllexport) 有...
  • Lua中的#

    2020-11-24 17:28:57
    lua的table可以用数字或字符串等作为key, #号得到的是用整数作为索引的最开始连续部分的大小, 如果t[1] == nil, 即使t[5], t[6], t[7]是存在的,#t仍然为零。对于这类tb[1],tb[2]....才能获取到正确的长度。 ...
  • lua 堆栈介绍

    2020-11-23 12:03:49
    一、Lua堆栈 要理解Lua和C++交互,首先要理解Lua堆栈。 简单来说,Lua和C/C++语言通信的主要方法是一个无处不在的虚拟栈。栈的特点是先进后出。 在Lua中,Lua堆栈就是一个struct,堆栈索引的方式可是是正数也可以...
  • Lua中#的解读

    千次阅读 2018-11-01 12:08:44
    table t 的长度被定义成一个整数下标 n 。 它满足 t[n] 不是 nil 而 t[n+1] 为 nil; 此外,如果 t[1] 为 nil ,n 就可能是零。 对于常规的数组,里面从 1 到 n 放着一些非空的值的时候, 它的...
  • 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与C/C++的基本交互,但是如果按照那样来使用的话,实在太麻烦了,所以我们开始进行封装。本篇博客主要记录C++调用Lua函数的封装。 封装目标 C++调用Lua,复杂的地方主要在于需要去理解Lua...
  • Lua C++交互机制

    千次阅读 2017-08-16 16:13:46
    一、LuaC++的交互机制——Lua堆栈1)交互机制LuaC++ 的交互机制的基础在于Lua提供了一个虚拟栈,C++Lua之间的所有类型的数据交换都通过这个栈完成 栈中每个元素都能保存任何类型的Lua值(实际上Lua的任何类型...
  • Lua 是一个小巧的脚本语言,它本身就是作为嵌入脚本而设计的,在目前所有脚本引擎中,Lua的速度是最快的。而且它的解释器非常轻量,其解释器不过200k(不同版本可能略有差异)。 Lua项目包含许多技术点,花些时间...
  • lua——C/C++lua嵌入式开发

    千次阅读 2017-04-01 18:17:10
    首先介绍一下Lua语言,Lua 是一个...lua本身就是C写的,所以Lua脚本可以很容易的被C/C++代码调用,也可以反过来调用C/C++的函数 lua语法、解释器、执行原理都与python相似 唯一差距就是lua没有强大的类库作为支撑,Lua
  • c++调用lua 函数之 lua_API

    千次阅读 2015-11-12 14:55:19
    转载自:http://www.cnblogs.com/ringofthec/archive/2010/10/22/lua.html http://www.cnblogs.com/ringofthec/archive/2010/11/04/luaapi.html ...
  • Lua嵌入C++

    2018-11-27 20:14:36
    本来是想看下lua文件的编码格式的不同跟 C++中的多字节和单字节有没有关系。就想建立一个工程实验一下,发现没有关系。lua文件的编码方式应该只能是不带bom的utf8 或者 ansi,这跟lua的解释器有关系。 在这个过程...
  • c++lua

    2017-01-15 22:26:34
    原帖地址: http://www.cnblogs.com/sevenyuan/p/4511808.htmllua和c++的交互就是通过一个无处不在的栈来实现的,此图如此传神啊! #include <iostream> #include <string.h> ... #include "lua.h
  • C++对象绑定到Lua

    千次阅读 2012-04-25 10:16:30
    游戏中的使用脚本语言已经成为了一个标准应用。脚本语言能够在游戏开发中扮演一个重要的角色,并且让数据结构化,计划事件,测试和调试这些工作更加容易。脚本语言也能够允许像美术,策划这些非程序专家通过一个高层...
  • c++读取lua配置基础类

    千次阅读 2014-05-20 12:59:00
    参考 http://www.360doc.com/content/11/1225/12/1317564_174843428.shtml
  • 此例演示了如何将C++对象导出到lua,并且可以在lua脚本中给这个导出对象添加新方法。C++所编写的对象方法和lua脚本所编写的对象的方法在两种语言中都可以互相调用。此例演示了如下特征:导出方法写在Lunar::RegType ...
  • Lua绑定C++

    千次阅读 2014-03-20 17:32:49
    原文:http://blog.csdn.net/chenee543216/article/details/12074771 以下是代码: Animal.h文件 #pragma once #ifndef __ANIMAL_H__ #define __ANIMAL_H__ class Animal { public: Animal( const char *name );
  • LuaC++交互总结(很详细)

    万次阅读 多人点赞 2014-09-07 18:50:37
    1.lua堆栈。 2.c++调用lua。 3.lua调用c++(静态链接方式和dll方式)。
  • 一、LuaC++的交互机制——Lua堆栈 LuaC++ 的交互机制的基础在于Lua提供了一个虚拟栈,C++Lua之间的所有类型的数据交换都通过这个栈完成。无论何时C++想从Lua中调用一个值,被请求的值将会被压入栈,无论何时...
  • LuaC++交互详细总结

    2016-03-18 16:10:29
    要理解LuaC++交互,首先要理解Lua堆栈。 简单来说,Lua和C/C++语言通信的主要方法是一个无处不在的虚拟栈。栈的特点是先进后出。 在Lua中,Lua堆栈就是一个struct,堆栈索引的方式可是是正数也可以是负数,...
  • lua调用c++

    2014-07-17 16:25:39
    本以为在Lua中使用C++的类一件非常复杂的事情。毕竟C++的类与Lua有那么多的不同。但是,困难都是纸老虎,只要想办法问题很容易就解决了。  首先,我们要搞明白C++中类和对象的概念。这个概念想要表述清楚是很难的...
  • 浅析C++绑定到Lua的方法

    千次阅读 2014-11-06 19:52:49
    虽然将C++对象绑定到Lua已经有tolua++、LuaBridge和luabind等各种库可以直接使用,但弄清楚C++对象绑定到Lua的常见方法,不但有助于更深的了解Lua的机制,还可以方便修改第三方库以满足实际项目需求。本文通过分析第...

空空如也

1 2 3 4 5 ... 20
收藏数 2,963,956
精华内容 1,185,582
关键字:

lua