Lua中每个值都可具有元表。 元表是普通的Lua表,定义了原始值在某些特定操作下的行为。你可通过在值的原表中设置特定的字段来改变作用于该值的操作的某些行为特征。...例如,当数字值作为加法的操作数时,Lua检查其元表中的"__add"字段是否有个函数。如果有,Lua调用它执行加法。 我们称元表中的键为事件(event),称值为元方法(metamethod)。...不能从Lua中改变其他类型的元表(除了使用调试库);必须使用C API才能做到。 表和完整的用户数据具有独立的元表(尽管多个表和用户数据可共享元表);每种其他类型的所有值共享一个元表。...这些操作的语义通过一个Lua函数描述解释器如何执行操作作了更好的说明。 下面显示的Lua代码只是说明性的;真实的行为被硬编码到解释器中,并且比这里的模拟更加高效。...,而且访问没有元表的对象不会失败(只是结果为nil)。
Lua作为一种很强大且轻量级脚本语言的存在,对于掌握其几乎无所不能的Table(其实就是一个Key Value的数据结构,它很像Javascript中的Object,或是PHP中的数组,在别的语言里叫Dict...对于Lua语言可参见酷壳Lua简明教程这篇Blog。...对于lua的table排序问题,一般的使用大多是按照value值来排序,使用table.sort( needSortTable , func)即可(可以根据自己的需要重写func,否则会根据默认来:默认的情形之下...,如果表内既有string,number类型,则会因为两个类型直接compare而出错,所以需要自己写func来转换一下;也可根据自己的需要在此func中 添加相应的逻辑来达到你的 排序要求); local...;这样的实现方式其实与上述将table的索引存入一个temp表中,并将此temp表按func排序;只不过这里 使用闭包,将此处理放置在了一个方法内来替代pairs罢了;
__tostring __tostring(a) --字符串输出 ,当调用tostring(obj)的时候,会先查找obj的元方法中的__tostring,如果有就调用,没有就会打印obj的内存地址
__index元方法 Lua 查找一个表元素时的规则,其实就是如下 3 个步骤: 1.在表中查找,如果找到,返回该元素,找不到则继续 2.判断该表是否有元表,如果没有元表,返回 nil,有元表则继续...3.判断元表有没有 __index 方法,如果 __index 方法为 nil,则返回 nil;如果 __index 方法是一个表,则重复 1、2、3;如果 __index 方法是一个函数,则返回该函数的返回值
从很多意义上讲,Lua语言中的一张表就是一个对象。首先,表与对象一样,可以拥有状态。...不过,Lua语言无法在表a中找到字段”deposit”,所以它会在元表的index中搜索。此时的情况大致如下: getmetatable(a)....请注意,当一个表的元表中的index字段为一个函数时,当Lua不能在原来的表中找到一个键时就会调用这个函数。基于这一点,就可以让index元方法在其他期望的任意数量的父类中查找缺失的键。...首先,Lua语言在account中找不到字段”getname”;因此,它就查找account的元表中的index字段,在我们的示例中该字段为NamedAccount。...为了避免未授权的访问,表示对象状态的表不保存在其他表的字段中,而只保存在方法的闭包中。
目录 0. redis中运行lua的流程的正常流程 1.redis中的lua概要信息 1.1 lua中调用redis命令 1.2 redis数据结构与lua数据结构对应关系 ...Redis 3.2以后支持) 2.3 lua脚本中的可选复制命令 3. redis中lua脚本的debug 3.1 lua脚本中记录日志 3.2 Lua debugger...1.redis中的lua概要信息 1.1lua中调用redis命令 在lua脚本中以2种方式调用redis的命令 lua中调用redis的方式 对异常处理的方式 redis.call 遇到异常将抛出...RedisTemplate调用execute方法,第一个参数是脚本对象,第二个参数是个列表对应乱脚本中的KEYS,之后的可变参数对应lua脚本中的ARGV。.../lock1.lua")); script.setScriptSource(scriptSource); //3.设置Lua脚本中的KEYS对象 Listkeys
LUA中的对象 我们知道,对象由属性和方法组成。LUA中最基本的结构是table,So 必须用table描述对象的属性。lua中的function可以用来表示方法。...那么LUA中的类 可以通过table + function模拟出来。至于继承,可以通过metetable模拟出来(不推荐用,只模拟最基本的对象大部分时间够用了)。 2....Metatable Lua中的metatable 类似于C++中的虚函数,当索引table中的项不存在时,会进一步索引metetable(如果设置了的话)是否存在该项。这跟虚函数概念 不是很吻合么?...__index 是跟设置metatable有关,详细信息参见lua manual http://www.lua.org/manual/5.1/ 实际上__index 应该赋值为function,这里是一个语法糖...实现继承 原理就是利用metatable,__index 设置这样的function,当前类不存在某项时,尝试去基类中查出 person_t = {} person_t.
如果Lua语言找到了该字段,就调用该字段对应的值,即所谓的元方法,在本例中就是用于计算表的和的函数。 可以认为,元表是面向对象领域中的受限制类。像类一样,元表定义的是实例的行为。...Lua 语言就使用这个元方法,与第二个值无关;如果第二个值有元表且元表中存在所需的元方法,Lua 语言就使用这个元方法;否则,Lua 语言就抛出异常。...因此我们可以修改表被遍历的方式和为非表的对象增加遍历行为。当一个对象拥有__pairs元方法时,pairs会调用这个元方法来完成遍历。...Lua语言还提供了一种改变表在两种正常情况下的行为的方式,即访问和修改表中不存在的字段。 __index元方法 正如我们此前所看到的,当访问一个表中不存在的字段时会得到nil。...组合使用元方法index和__newindex可以实现Lua语言中的一些强大的结构,例如只读的表、具有默认值的表和面向对象编程中的继承。 具有默认值的表 一个普通表中所有字段的默认值都是nil。
,当需要区分整型值和浮点型值时,可以使用函数math.type: >math.type(3) --integer >math.type(3.0) --float 在Lua5.3中: >3 -...因此,数值的表示在范围和精度上都是有限制的。标准Lua使用64个比特位来存储整型值,其最大值为2^{63}-1,约等于10^{19};精简Lua使用32个比特位存储整型值,其最大值约为20亿。...数学库中的常量定义了整型值的最大值(math.maxinteger)和最小值(math.mininteger)。...64位整型值中的最大值是一个很大的数值:全球财富总和(按美分计算)的数千倍和全球人口总数的数十亿倍。尽管这个数值很大,但是仍然有可能发生溢出。...>math.maxinteger + 2.0 -- 9.2233720368548e + 18 在上例中,两个结果从数学的角度看都是错误的,而且它们错误的方式不同。
引言 在上篇博客中,我们简单地学习了一下Lua的基本语法。其实在Lua中有一个还有一个叫元表的概念,不得不着重地探讨一下。元表在实际地开发中,也是会被极大程度地所使用到。...本篇博客,就让我们从Lua查找表元素的过程,来探讨学习一下Lua中的元表。 一、什么是元表 在Lua table中我们可以访问对应的key来得到value值,但是却无法对两个table进行操作。...很多人对Lua中的元表和元方法都会有一个这样的误解:“如果A的元表是B,那么如果访问了一个A中不存在的成员,就会访问查找B中有没有这个成员”。...如果尝试访问了一个表中并不存在的元素时,就会触发Lua的一套查找机制,Lua也是凭借这个机制来模拟了类似“类”的行为。...输出为nil的原因很简单,myTable中并没有prop2这个成员,这符合我们平时操作Dictionary的习惯。但对于Lua的表,如果myTable有元表和元方法,情况就不同了。
前言项目中由于对于启动的优化,配置表量并不是特别大,但启动时长却不低,但对于应用类来说,对启动时长要求很严格。...我希望能做到毫秒级的加载体验,所以有了这个优化旧方案使用pb表配置,用工具转成pb格式,启动后加载到lua table原始的pb文件在2M多,读取到内存中后,会增加20多M的内存开销加载时长是高端机500ms...,也是用工具预先转换一下 【】文件头 【】列信息 【】数据表中全部字符串 【】不定长的数组 【】关键列查找表 【】行数据(定长结构,如果该列是字符串这类的不定长数据...【N】 【值或偏移】通过重载 __index, 直接查找返回相应的变量,也正常的lua table访问基本一致优化思路1、采用内存文件格式,内存格式与文件格式完全一致,这个完全去除了数据解码的开销...这样配置文件大小与CPU的性能就不相关了,完全能满足毫秒级的加载体验2、数据压缩,减少内存开销 自适应压缩整数,对于boo, 小于255的整数,使用1Byte存储 对于小于
1)lua的GC默认是自动回收的,当一个对象的引用计数为0时,它就会被GC所回收。...2)lua中的表默认是强引用的,当你把某个对象放入表中时,就是生成一个对它的强引用(对象的引用计数+1),在对象的引用计数没有为0之前不会被GC回收; 3)如果把一个表声明为弱引用,则当把某个对象放如表中时...,生成一个弱引用(对象不会被引用计数,可以理解为引用计数+0);如果一个对象只被弱引用表所引用(对象的引用计数为0),则会被下一次GC自动回收 所以弱引用表weak table的用途一般都是出于GC考虑的...注意:以上所指对象不包括值类型:number、boolean 当K为弱引用 t = {} --标记表t的key为弱引用 setmetatable(t, {__mode = "k"}) key1 =...,t中也访问不到key1了 如果注释setmetatable(t, {__mode = “k”}) 这个语句,t[key1] 会导致key1引用 +1,即使 key1 = nil ,仍然访问到t[key1
*L); 打开所有的标准lua库到指定状态,也就是把所有标准类库加载到指定的虚拟机....的区别 LUAL_LOADFILE的坑 lua_pcall int lua_pcall (lua_State *L, int nargs, int nresults, int msgh); nargs:...参数个数 nresults:返回值个数 errFunc:错误处理函数,0表示无,表示错误处理函数在栈中的索引 在保护模式下调用一个函数 lua_getglobal void lua_getglobal...(lua_State *L, const char *name); 将全局名称的值压入堆栈 lua_newtable void lua_newtable (lua_State *L); 创建一个新的...lua_settable void lua_settable (lua_State *L, int index); 就是把表在lua堆栈中的值弹出来,index 是table 在堆栈中的位置,假如 table
概述: lua要实现类,继承,多态 BaseClass(super)为生成基类公共方法,内部开辟新的以class_type为模板返回,主要为类的声明服务,一个类有的__init(构造),__delete...(析构),.super(父类),.New(创建对象),setmetatable(class_type, {__index = _class[super]})设置元表,__index指向父类 类的声明BaseView...= BaseView or BaseClass() 类的继承LoginView = LoginView or BaseClass(BaseView) 通过设置class_type.New,会再返回一个新的设置子类的元表...再注册DeleteMe方法,依次调用子类__delete,父类__delete --保存类类型的虚表 local _class = {} local lua_obj_count = 0 function...lua_obj_count = lua_obj_count + 1 -- 生成一个类对象 local obj = {_class_type = class_type} --原始表,表里有个key
10 , y = 20} f({x = 10 , y = 20}) type{} Lua语言也为面向对象风格的调用提供了一种特殊的语法,即冒号操作符。...形如x:foo(x)的表达式意味为调用对象o的foo方法。 一个Lua程序既可以调用Lua语言编写的函数,也可以调用C语言编写的函数。...要遍历可变长参数,函数可以使用表达式{…}将可变长参数放在一个表中,就像add示例中所作的那样。不过,在某些罕见的情况下,如果可变长参数中包含无效的nil,那么{…}获得的表可能不再是一个有效的序列。...此时,就没有办法在表中判断原始参数究竟是不是以nil结尾的。对于这种情况,Lua语言提供了函数table.pack。...该函数像表达式{…}一样保存所有的参数,然后将其放在一个表中返回,但是这个表还有一个保存了参数个数的额外字段”n”。
Lua语言通过不使用全局变量的方法来解决这个难题,但又不遗余力地在Lua语言汇总对全局变量进行模拟。在第一种近似的模拟中,我们可以认为Lua语言把所有的全局变量保存在一个称为全局环境的普通表中。...由于不需要再为全局变量创造一种新的数据结构,因此使用一个表来保存全局变量的一个优点是简化了Lua 语言的内部实现。另一个优点是,可以像操作其他表一样操作这个表。...由于Lua语言将全局变量存放在一个普通的表中,所以可以通过元表来访问不存在全局变量的情况。...,即Lua语言内部维护的一个普通的表。...不过,任何赋值都会发生在新表中,虽然我们仍然能通过_G来修改全局环境中的变量,但如果误改全局环境中的变量也不会有什么影响。
作为Lua中实现各类数据结构的基石,表的使用想必是贯穿于整个项目的开发过程之中,其中对表内容的排序想必亦是常见的需求之一,Lua内置的Table函数库便提供了sort函数来实现这项功能,但是仅能支持表中数组部分内容的排序...,而想要排序表中哈希部分的内容,简单的一个方法就是另写一个迭代器来支持: function order_pairs(tbl) local names_buffer = {} for name...= names_buffer[table_index] return key, tbl[key] end return iterator end 写个简单的测试...pairs", [2] = "another", a = "string" } print_table(t) print_table_order(t) 基本就是这么简单~ 更新: 其实之前的实现有两个问题...,使用默认的comp实现(简单的基于字符串比较),在某些情况下会得到非期望的排序结果(依赖于字符串比较的实现方式),再者也缺少扩展性,无法定制comp,更好的实现方式还是开放comp的设置,并提供默认实现
游戏脚本制作过程中需要持久化部分数据,经过技术可用性分析,字符串与表互转不可以再游戏中持久化。存储到本地IO 成本也比较高,可以尝试一下。...return retstr end 具体使用 local tb = { [1] = "A"; [2] = "B"; [3] = "C"; [4] = "D"; } -- 表转字符串...local strtb = TableToStr(tb) print(strtb) -- 字符串转表 local newtb = StrToTable(strtb) for k,v in...ipairs(newtb) do print(k,v) end 特殊说明: 解决问题的光鲜,藏着磕Bug的痛苦。...以上文章,均是我实际操作,写出来的笔记资料,不会出现全文盗用别人文章!烦请各位,请勿直接盗用!
接着lua的使用,迭代器、模块和元表,元表为重点需要关注的内容 一、迭代器 pairs就是一个迭代器,它的返回值是key和value,下面自定义一个迭代器 定义迭代器语法: function 迭代器名...end -- in后面,跟上迭代器名,终止值,初始值 for i,d in double,10,0 do print(i,d) end 运行结果: image.png 二、模块 lua5.1...开始支持模块,可以将函数封装进模块中,在别的脚本中引用模块 1....元表允许改变table的行为,对table变相的进行扩展,甚至能达到模拟类的功能 1....print(e['c']) print(e[1]) 运行结果: 3. newindex元方法 newindex元方法定义方式为{__newindex = 值},也有两种用途 3.1 将新元素存入另一张普通表中
中sock变量会被GC掉,就要从Lua的基本规则说起: 在Lua中,一共有8种基本类型: nil、boolean、number、string、function、userdata、 thread 和 table...其中’string,function,userdata,thread,userdata’等需要额外分配内存的数据类型均受Lua中的GC管理。...以往写Lua代码时,我一直以为Lua是“原型对象”编程范式,然而这个“大跟头”让我发现,原来Lua的底层基石竟然是“函数式编程”范式(非纯函数式编程语言,Lua中的函数有副作用)。...在面向对象编程中,万物皆对象”。 然后你(主要是我自己)就开始似懂非懂的用这些概念去“忽悠”其他人。...自身的GC机制会保证,在函数(闭包)没有被回收前,其携带的环境变量永远有效。 在Lua的require和chunk的机制中我摔的跟头充分验证了这一点。
领取专属 10元无门槛券
手把手带您无忧上云