Lua 中的表达式模板

lua-users home
wiki

表达式模板是 C++ 中的一种技术,用于将表达式作为函数参数传递并操作这些表达式。 [Veldhuizen] 更多背景信息可以在 [1][2] 中找到。

以下是在 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)不能在该技术中的表达式内使用。

--DavidManura

另请参阅


最近更改 · 偏好设置
编辑 · 历史记录
最后编辑于 2009 年 5 月 7 日凌晨 3:49 GMT (差异)