lua | 利用元表实现修饰器
Posted 自科部
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lua | 利用元表实现修饰器相关的知识,希望对你有一定的参考价值。
这次终于把字体大小弄对了,以前是用rem(相对文档大小)做单位的,在一部分手机上会出现字体偏大的现象,现在改用em做单位,应该没事了,如果还有问题只能用终极武器px了
基础概念
元表(metatable)
弱表(weak table)
运算符重载
修饰器
概述
有时我们要为一些对象增加元数据(文档,变量类型什么的),但有时对象是从别处来的,没法修改内部,所以要用到修饰器。
注:本文的对象指lua中的table,function,userdata等。
什么是修饰器?
修饰器可以理解成数学中的算子,接受一个函数,返回修饰过的一个函数,例如微分算子 ,可以返回函数的导函数。修饰器与它类似,就是接受一个对象,返回修饰过的对象。
文档字符串(docstring)
用来说明对象的功能,使用方法的一个字符串,随着对象传递,可以使用特定的函数获取该字符串(例如py中的help函数)。
利用元表模拟文档修饰器
利用lua强大的元表功能,可以很方便的实现修饰器,给对象增加docstring。在lua的中,每一个对象可以用作table的key,也就是所谓的弱表(weak table,具体见《lua程序设计第一版》第十七章 weak 表)。所以只要建立一个全局表,用对应对象做key,来存储每个对象的docstring,就可以了,具体实现:
local docstrings = setmetatable({}, {__mode = "kv"})
function document(str)
return function(obj) docstrings[obj] = str; return obj end
end
function help(obj)
print(docstrings[obj])
end
document[[Print the documentation for a given object]](help)
document[[Add a string as documentation for an object]](document)
f = document[[Print a hello message]](
function()
print("hello")
end
)
f()
help(f)
代码来自lua-user wiki
用运算符重载
像下面这个:
random =
docstring[[Compute random number.]] ..
typecheck("number", '->', "number") ..
function(n)
return math.random(n)
end
重载了..
运算符,为什么要这样?这样就可以省去一对括号,让人看不出docstring是一个函数= =
可以用下列代码实现:
mt = {__concat =
function(a,f)
return function(...)
print("decorator", table.concat(a, ","), ...)
return f(...)
end
end
}
function typecheck(...)
return setmetatable({...}, mt)
end
function docstring(...)
return setmetatable({...}, mt)
end
btw,除了..
运算符,你也可以重载别的,反正看起来好看就行。
以上是关于lua | 利用元表实现修饰器的主要内容,如果未能解决你的问题,请参考以下文章