字符串索引 |
|
a[5]
来表示字符串 a
的第五个(或者可能是第六个)字符。在 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) 停止工作,并出现错误 "bad argument #2 to 'sub' (number expected, got string)" 在 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