表格函數 |
|
do local meta = {__call = function(t, ...) return t.__function(t, unpack(arg)) end } function Tablefunc(fn) return setmetatable({__function = fn}, meta) end end
「表格函數」的結果是語意呼叫的表格,但函數具有隱含的第一個引數,就是函數本身的表格,函數可以在其中儲存持續狀態。
我知道你在想什麼。那又怎樣?這只是一個沒有金鑰的標準物件呼叫而已。如果我要私人持續狀態又該怎麼辦?好吧,看看「表格函數 2」
同時,這裡有一個快速且愚蠢的範例
repeater = Tablefunc( function(self, n, str) -- I've got persistent state variables self.times_called = (self.times_called or 0) + 1 -- I can get at the base function and even change it -- so it will do something different next time if self.times_called >= 99 then self.__function = function() return "Sorry, I'm tired of repeating myself" end end -- I can use the table for configuration, and -- the functable itself is self, so I can recurse if n == 0 then return "" elseif n == 1 then return str else return str .. (self.delim or ", ") .. self(n - 1, str) end end)
強制範例執行
$ lua Lua 5.0 (beta) Copyright (C) 1994-2002 Tecgraf, PUC-Rio > -- I can get at the state variables from here, too > repeater.delim = "; " > print(repeater(7, "hello")) hello; hello; hello; hello; hello; hello; hello > print(repeater.times_called) 7 > _ = repeater(90, "hello") > print(repeater.times_called) 97 > print(repeater(7, "hello")) hello; hello; Sorry, I'm tired of repeating myself
──RiciLake
function wrap(fn) local t = {} return function(...) return fn(t, ...) end, t end
local states = setmetatable({}, {__mode = "kv"}) function addstate(fn) local t = {} local fn2 = function(...) return fn(t, ...) end states[fn2] = t return fn2 end function getstate(fn) return states[fn] end