Lua 绳索 |
|
由于字符串在 Lua 中是不可变对象,因此避免不必要地创建字符串非常重要。程序经常操作字符串以创建一些文本输出。一种策略是避免创建中间字符串,而是按正确顺序输出最终文本的所有部分。适合此目的的数据类型是绳索[1],其中
rope ::= string | list of rope换句话说,绳索是一棵树,其叶子是字符串。树上的重要操作是树遍历,将过程应用于每个叶子。
do local function walk(x,f) local typ, ok, bad = type(x),true local errmsg = "bad type (%s), %s" if typ == "string" then return pcall(f,x) elseif typ == "table" then local i,n = 1,#x while ok and i <= n do ok,bad = walk(x[i],f) i = i+1 end -- while return ok,bad else bad = errmsg:format(typ,typ and "" or "something undefined?") return nil,bad end -- if end -- function local mt = { push = function (self,x) local function f(y) if y and type(y) ~= "function" then self[#self + 1] =y return f elseif y then return function (z) return f(y(z)) end -- function end -- if end -- function y return f(x) end; -- function push walk = walk; flatten = function(self) local o = {} local f = function (x) o[#o + 1] = x end -- function self:walk(f) return table.concat(o) end; -- function } function rope() return setmetatable({}, {__index = mt}) end -- function end -- do t,x = rope(),rope() t:push (string.upper) "m" "r" (string.char) (32) "Smith" ; x:push [[ Good ]] [[morning]]; t:push (x) t:walk(io.write) --> Mr Smith Good morning print(t:flatten()) --> Mr Smith Good morning