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

另請參閱


RecentChanges · 偏好設定
編輯 · 歷史記錄
最後編輯時間:2009 年 5 月 7 日上午 3:49 GMT (diff)