Lua 中的表达式模板 |
|
以下是在 Lua 中使用类似表达式模板的技术的示例。
-- Expression object. local expression_mt = {} function Expression(name) return setmetatable( {name=name, eval=function(vars) return vars[name] end}, expression_mt) end local function eval(o, vars) if type(o) == 'table' then return o(vars) else return o end end function expression_mt.__add(a, b) return setmetatable( {eval=function(vars) return eval(a, vars) + eval(b, vars) end}, expression_mt) end function expression_mt.__pow(a, b) return setmetatable( {eval=function(vars) return eval(a, vars) ^ eval(b, vars) end}, expression_mt) end function expression_mt.__call(a, vars) return a.eval(vars) end -- auto-create expression objects from globals local G_mt = {} function G_mt:__index(k) return Expression(k) end setmetatable(_G, G_mt) -- example usage: local function sum(expr, first, last) local result = 0 for x=first,last do result = result + expr{x=x} end return result end print( sum(x^2 + 1, 1, 10) ) --> 395
比较
print( sum(x^2 + 1, 1, 10) )
与更传统的方法
print( sum(function(x) return x^2 + 1 end, 1, 10) )
在后一种情况下,函数“function(x) return x^2 + 1 end
”对于函数 sum
来说是一个黑盒(除了 sum
对函数执行 string.dump
并检查字节码)。sum
只能调用该函数,但无法看到其内部实现。在前一种情况下,x^2 + 1
中的各个操作可以被 sum
访问。
为了说明这种方法的强大之处,可以改写示例以对表达式进行符号积分 [1]
print( integral(x^2 + 1) ) --> expression object representing the --- polynomial (1/3)*x^3 + x print( sum(integral(x^2 + 1), 1, 10 ) --> 1063.333...
请注意,Lua 中不支持元方法的操作(例如 and
/or
/not
)不能在该技术中的表达式内使用。