对应目前最新lua5.4 beta版本:2019-10-09发布html
这个功能以前修改过两次语法,当前的语法不出意外将会是最终决定了,目前尚未最新的中文资料,因此我来这里发一下。c++
先介绍下这个功能:函数
被标记为to-be-closed的局部变量,会在超出它的做用域时,调用它的__closed元方法,这就为咱们提供了相似C++析构函数的做用。lua
因此一个被标记为to-be-closed的变量应该符合两个前提条件:spa
一、它是一个table设计
二、已经为它指定了__close元方法code
当前版本语法:在变量名后添加<close>,将变量标记为to-be-closed变量htm
local t<close> = ...blog
示例:作用域
function test2() local t = {x=1}; setmetatable(t, {__close=function(...) print('close') end}); local tc<close> = t; --函数返回时,将自动执行tc的__close元方法。 end test2(); -- 以文件操做为例: -- 在没有to-be-closed变量的状况下: function foo() -- 打开一个文件 local fd = io.open('c:\\1.txt', 'r'); -- 读取文件 local x = fd:read('*a'); -- 接下来就是对文件内容进行判断 -- 假如咱们在逻辑上须要多种内容 if x == '1' then fd:close(); return; else if x == '2' then print('文件内容为:2'); fd:close(); return; end print('错误的文件内容:'..x); fd:close(); end -- to-be-closed的状况下: function foo2() -- 在变量名以后添加<close> local fd<close> = io.open('c:\\1.txt', 'r'); -- 接下来就和 各类返回位置都要写的超级烦人的fd:close()说再见 -- 读取文件 local x = fd:read('*a'); if x == '1' then return; else if x == '2' then print('文件内容为:2'); return; end print('错误的文件内容:'..x); end -- 以实现c++的std::lock_guard为例: -- xshare.lock xshare.unlock来自于个人另外一篇文章:https://www.cnblogs.com/babypapa/p/11711389.html function lock_guard(xt) local t = {xstab = xt}; setmetatable(t, {__close=function(tab) xshare.unlock(tab.xstab) end}) xshare.lock(xt); return t; end function foo3(xt) local lg<close> = lock_guard(xt); ... end
而后,下面是吐槽
我只能说,罗伯托老兄不知道是在什么状况下的考虑,而设计出这种东西的,这绝对是思惟掉坑了。
若是只考虑元方法,你偷懒就偷懒了,用表来实现,是能够理解的。
但使用了新的语法时,再依赖过去的元方法,就关系就混乱了,
语法是什么?更底层的东西。
而元方法的实现,首先暴露给用户的入口点就是一个函数。
而后很显然,底层依赖上层的关系出现了。
再来看同期的产物,const变量,只有local v<const> = ...这样的方式,而且它不做用于table内部。local t<const> = {a=1, b = 2}; t.a=11照样能够改。
当一个const变量,只能本地储存的时候,咱们为什么还要脱裤子放屁,我感受,怕不是我本身对常量的定义有本质的误解。
我就想说,把const设计成一个函数很差吗?
local a, b, c = const(1, 2,3)
x,y,z = const(1,2,3)
local t = const({const(1, 2, 3)})
t = {const(1), 2, const(3)}
这种方式不比<const>容易实现,不能更容易知足你们的需求?
最后我想说,若是再继续偷懒,等到哪一天,这些问题被用户习惯掉以后,就像nil的天坑没法改变的时候,就晚了。