字串索引 |
|
a[5]
表示字串 a
的第 5 個(或第 6 個)字元。但 Lua 中不行。你必須寫成 a:sub(5,5)
或 string.sub(a,5,5)
。我們可以做點什麼嗎?從 Lua 5.1 開始,是的。這樣的話
getmetatable('').__index = function(str,i) return string.sub(str,i,i) end -- demo a='abcdef' return a[4] --> d
| 我遇到一些問題:在這些程式碼執行後 s:sub(2) 會停止運作,並伴隨著錯誤訊息「傳給 sub 的第 2 個引數錯誤 (應為數字,但收到字串)」已在 Lua 5.2.4 /d9k 上進行測試
local strdefi=getmetatable('').__index getmetatable('').__index=function(str,i) if type(i) == "number" then return string.sub(str,i,i) else return strdefi[i] end end
但字串,比如 a[3,5]
呢?不行,那是錯的。我們必須使用 __call 元方法才行。
getmetatable('').__call = string.sub -- demo a='abcdef' return a(3,5) --> cde return a(4) --> def -- equivalent to a(4,-1)
讓我們發揮創意,實現 Luiz 本人的建議。 [1]
getmetatable('').__index = function(str,i) return string.sub(str,i,i) end getmetatable('').__call = function(str,i,j) if type(i)~='table' then return string.sub(str,i,j) else local t={} for k,v in ipairs(i) do t[k]=string.sub(str,v,v) end return table.concat(t) end end -- demo a='abcdef' return a[4] --> d return a(3,5) --> cde return a{1,-4,5} --> ace
注意:使用這個簡單的 __index 方法,你將失去對字串呼叫函數的能力,例如 a:match('abc')
。你需修改 __index 如下所示
getmetatable('').__index = function(str,i) if type(i) == 'number' then return string.sub(str,i,i) else return string[i] end end
如果你不喜歡的話,你可以省略對 __index 的重新定義,並使用 a{4}
取代 a[4]
。
請務必記住,這些索引函數選擇的是位元,而不是字元。例如,UTF-8 字元佔用可變個數的位元:請參閱討論 ValidateUnicodeString。
Lua = 'Lua' print (Lua(1,3)) --> L