博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Lua 函数 类 Table --学习笔记
阅读量:6648 次
发布时间:2019-06-25

本文共 3187 字,大约阅读时间需要 10 分钟。

hot3.png

--[[

Table:

元方法: 当表达式中混合了不同元表的值时, 先看第一个值有无对应元表, 没有再看第二个对象的.

两个对象都没有,应发一个错误. 

算术类的:__add加法, __mul乘法, __sub减法, __div, __unm(相反数), __mod取模, __pow乘幂, __concat连接操作符

关系类的:__eq等于, __lt小于, __le大于, 其他的进行转换:a~=b=>not(a==b), a>b=>b<a, a>=b=>b<=a

库定义的:__tostring, __metatable, 设置__metatable="xxx", getmetatable返回"xxx", setmetatable

引发错误, 起到不能设置元表的保护作用.

关于访问的:

__index: 访问table中不存在的字段时, 没有这个元方法时返回nil, 有的话, 由它返回结果.

__newindex: 当对table中不存在的索引赋值时, 查找它, 调用它而不是赋值, 如是一个table,在此table

中赋值,而不是原来的table.

插入/删除: 一般下标从1开始

table.insert(t,index,v) 指定位置插入元素, 后续元素往后移动

table.insert(t,v) 没有位置参数,添加到数组末尾, 这可以实现  栈--压入

table.remove(t)  栈--弹出

table.insert(t,1,v) 起始处插入, 实现 队列--入队

table.remove(t,1)  从另一端删除(并返回元素), 队列--出队   效率不高,需移动元素

排序: table.sort()

连接: table.concat()

]]--

--[[

函数: 

闭包,闭合函数, Lua可以说没有'函数', 都是closure, 函数是特殊的closure.

closure: 一个函数及访问的非局部变量(upvalue). 没有upvalue就是传统函数

 function newCounter()     local i = 0  --非局部变量upvalue     return function() --匿名函数         i = i + 1         return i     end end c1 = newCounter() --返回一个闭包:匿名函数和它访问的upvalue print(c1()) --执行 print(c1()) --同一个闭包 c2 = newCounter() --返回另一个闭包环境

沙盒:

 do     local oldOpen = io.open()     local accessOK = function(filename, mode)         --检查权限     end     io.open = function(filename, mode) --重新定义         if accessOK(filename, mode) then  --确保使用安全. 形成沙盒环境             return oldOpen(filename, mode) --调用原系统库函数         else             return nil, "access denied"         end     end end

尾调用消除:

尾调用: function f(x) return g(x) end --调用完g(x)无事可做. 

消除: 不需要返回f(),不保存它的栈信息, 直接返回调用f的点.  相当于g(x)就是goto的功能.

]]--

--类:

Account = {balance = 0} --balance是公有成员变量 --new可视为构造函数 function Account:new(o) o = o or {}  --将新对象实例的meatatable指向Account setmetatable(o,self) self.__index = self --Account的__index指向自己 return o  end --deposite被视为Account类的公有成员函数 function Account:deposit(v)     --这里的self表示对象实例本身     self.balance = self.balance + v     --这里得这么理解:local accout = Accout(Accout, {}); accout.deposite(accout,v) end --下面的代码创建两个Account的对象实例 --通过Account的new方法构造基于该类的示例对象。 a = Account:new() --[[ 这里需要具体解释一下,此时由于table a中并没有deposite字段,因此需要重定向到Account, 同时调用Account的deposite方法。在Account.deposite方法中,由于self(a对象)并没有balance 字段,因此在执行self.balance + v时,也需要重定向访问Account中的balance字段,其缺省值为0。 在得到计算结果后,再将该结果直接赋值给a.balance。此后a对象就拥有了自己的balance字段和值。 下次再调用该方法,balance字段的值将完全来自于a对象,而无需在重定向到Account了。 --]] a:deposit(100.00) print(a.balance) --输出100 b = Account:new() b:deposit(200.00) print(b.balance) --输出200 --下面将派生出一个Account的子类,以使客户可以实现透支的功能。 SpecialAccount = Account:new()  --此时SpecialAccount仍然为Account的一个对象实例 --SpecialAccount将为Account的子类,下面的方法withdraw可以视为SpecialAccount --重写的Account中的withdraw方法,以实现自定义的功能。 function SpecialAccount:withdraw(v)     --此时的self将为对象实例。     if v - self.balance >= self:getLimit() then         error("Insufficient funds")     end     self.balance = self.balance - v end

--在执行下面的new方法时,table s的元表已经是SpecialAccount了,而不再是Account。

s = SpecialAccount:new{limit = 1000.00}

--在调用下面的deposit方法时,由于table s和SpecialAccount均未提供该方法,因此访问的仍然是

--Account的deposit方法。

s:deposit(100)

--此时的withdraw方法将不再是Account中的withdraw方法,而是SpecialAccount中的该方法。

--这是因为Lua先在SpecialAccount(即s的元表)中找到了该方法。

s:withdraw(200.00)

print(s.balance) --输出-100

转载于:https://my.oschina.net/SethFeng/blog/300552

你可能感兴趣的文章
Node.js能让Javascript写后端,为啥不让Python写前端?
查看>>
陶哲轩实分析 习题 12.5.8 :度量空间中有界闭集不一定是紧集
查看>>
使用VS2012遇到的问题
查看>>
20.元素分类--内联块状元素
查看>>
出错。instantiating servlet class(无法实例化servlet)
查看>>
应该做什么样的研究:以Google为例
查看>>
Windows Phone 8.1 页面导航
查看>>
web前端工程师全套教程免费分享
查看>>
非对称加密相关基础
查看>>
Leetcode | Sum Root to Leaf Numbers
查看>>
在线求中位数
查看>>
Sql server在另一台服务器,在Visual Studio 中没问题,IIS中 提示“在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。。。。”...
查看>>
Zookeeper
查看>>
linux 系统备份还原
查看>>
动态生成Menu
查看>>
插入排序
查看>>
JDBC的封装
查看>>
记录Html+Css流程表格
查看>>
webform 复合控件
查看>>
硬盘分区后丢失的文件怎么恢复
查看>>