lua_lua5 - CSDN
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]
信息
外文名
lua
研究地点
巴西里约热内卢天主教大学
类    型
脚本语言
研究时间
1993年
lua保存和运行
运行可以通过 Lua 的交互模式,也可以用记事本编辑代码保存为 .lua 的格式,通过 Lua 编译器运行。也可以通过第三方工具,将 Lua 打包独立运行。
收起全文
  • Lua语言从入门到精通

    2018-10-22 21:38:05
    深入浅出Lua学习
  • <8>Lua从入门到精通

    2018-10-22 21:38:16
    lua语言以其,轻量级: 可扩展,支持面向过程编程和函数式编程;自动内存管理;只提供了一种通用类型的表(table),用它可以实现数组,哈希表,集合,对象;闭包(closure);提供多线程支持; 在 游戏开发,独立应用...
  • 本课程从实战角度讲解了流行的高性能脚本Lua与c++的联合开发,这套方案已经被大量的对性能由要求的系统使用,成为了高性能脚本的唯一方案,像大量的游戏在使用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-30 10:16:45
    女主宣言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快速使用指南

    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 中 . 和 : 的区别

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

    lua 中 . 和 : 的区别

    首先在lua中使用“:”定义的函数会自动传入一个名为self的变量,这个变量是隐含的,self同c++中的this一样,表示当前对象的指针:而“.”定义的函数中没有self。

      function  class:func2( )  end
      function  class.func1(self)  end
      --这时候这两个函数等价
    function MainScene:ctor()
        self:ceshi(1,2,3)
    end
    function MainScene:ceshi(a,b,c)
        print(a,b,c)
    end
    输出:1 2 3

    分析:默认传self,默认接受self。

    function MainScene:ctor()
        self:ceshi(1,2,3)
    end
    function MainScene.ceshi(a,b,c)  --注意是.
        print(a,b,c)
    end
    输出:userdata 1 2

    分析:调用ceshi函数时用的:默认传递self为第一个参数,但是函数声明的时候用的 . 所以不会有默认隐藏的self去接收,此时传递参数为 self 1 2 3 但是ceshi函数只接收3个参数所以3被抛弃。

    function MainScene:ctor()
        self.ceshi(1,2,3)  --注意是.
    end
    function MainScene.ceshi(a,b,c)  --注意是.
        print(a,b,c)
    end
    输出:1 2 3

    分析:默认不传递self,默认不接受self

    function MainScene:ctor()
        self.ceshi(1,2,3) --注意是.
    end
     
    function MainScene:ceshi(a,b,c)
        print(self)
        print(a,b,c)
    end
    输出:1
         2 3 nil

    分析:函数调用时用的 . 不会传递self 只传递1 2 3,而ceshi函数声明时用的 : 默认有一个self在第一位去接收,ceshi函数能接收4个参数,即 self a b c ,所以c没有接收参数为nil。 
    在lua中模拟面向对象编程中,可以用 . 来表示类方法,而 : 可以用来表示成员方法。

    展开全文
  • lua入门

    2019-03-08 17:19:24
    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官网:https://www.lua.org/ 点击GetStart 点击LuaDist 进入下载界面 点击Windows86进行下载: 下载好之后,进行解压就行: 解压之后,在Windows环境变量Path添加解压文件的bin目录: ...
  • [Lua]LuaAPI整理

    2015-03-11 18:41:02
    LUA和C/C++的沟通桥梁——栈 Lua生来就是为了和C交互的,因此使用C扩展Lua或者将Lua嵌入到C当中都是非常流行的做法。要想理解C和Lua的交互方式,首先要回顾一下C语言是如何处理函数参数的。 C函数和参数 大家知道...
  • xLua(一)——介绍

    2019-07-22 12:11:07
    一:什么是热更新? 热更新是指当游戏出现bug,或者需要修改,增加某个功能的时候,我们不需要重新下载安装包,就可以更新游戏内容 游戏上线后,遇见bug或者需要更新内容,一般有两种做法:第一种:重新打包上传一...
  • Lua编写iOS程序

    2012-10-08 11:39:04
    包括用Lua创建完整的应用(Corona)一直到用Lua作为app中的脚本元素(通过Wax或diy)。在此之前,我们需要问自己两个问题:1、为什么要使用Lua?2、苹果允许使用Lua吗?这两个问题是紧密相关的。如果你在此之前对Lua...
  • 一、什么是lua&luaJit lua(www.lua.org)其实就是为了嵌入其它应用程序而开发的一个脚本语言,luajit(www.luajit.org)是lua的一个Just-In-Time也就是运行时编译器,也可以说是lua的一个高效版。 二、优势 ...
  • 他们这种外挂很多都是用GG修改器修改本地代码然后实现游戏里的透视变色自瞄之类的变态功能,有GG不行还得有脚本,这里的脚本就是LUA脚本.这种脚本我就不做多解释了自己可以去百度一下!意思就是你只要把这脚本放到GG上...
  • Lua在Windows下的安装、配置、运行 本文提供全流程,中文翻译。 助力完成 Window 系统下纯净 Lua 编辑环境的安装 为新手节省宝贵的时间,避免采坑! 全文高清图片,点击即可放大观看 点击——下载/download ...
  • 众所周知,Lua是一种强大的脚本语言,并且这种语言是用C语言实现的。为什么要学习这门语言?因为它可以增强我看C语言代码的功底。我下的Lua版本是Lua5.3,关于Lua5.3的简介如下:...
  • luac给lua脚本加密

    2018-08-22 13:13:01
    项目要求对lua脚本进行加密,查了一下相关的资料 ,得知lua本身可以使用luac将脚本编译为字节码(bytecode)从而实现加密,试了一下,确实可行。 下面是使用原生的lua解释器编译字节码: 1、新建一个名为1.lua的文件,...
  • 相信有接触过游戏开发的童鞋都知道lua这个脚本语言,Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。关于lua的简介...
  • Redis:EVAL执行Lua脚本

    2018-08-07 16:54:28
    EVAL 脚本 numkeys 键[键....EVAL和EVALSHA用于从Redis2.6.0版本,开始使用内置在Redis中的Lua解释器来评估脚本。 EVAL的第一个参数是一个Lua 5.1脚本。脚本不需要定义一个Lua函数(不应该)。这只是一个将在Red...
  • 首先介绍一下Lua语言,Lua 是一个小巧的脚本语言,该语言的设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。 一:lua定位——C/C++嵌入式脚本语言 lua本身就是C写的,所以Lua脚本可以很...
1 2 3 4 5 ... 20
收藏数 131,646
精华内容 52,658
关键字:

lua