我正在尝试像 Python 一样向字符串添加索引。这有效:
getmetatable('').__index = function(str, i) return string.sub(str, i, i) end
str1 = 'hello'
print(str1[1])
Run Code Online (Sandbox Code Playgroud)
这不会:
getmetatable('').__index = function(str, i) return str:sub(i, i) end
Run Code Online (Sandbox Code Playgroud)
给出以下错误:
lua: test.lua:1: C stack overflow
stack traceback:
test.lua:1: in function '__index'
test.lua:1: in function '__index'
...
test.lua:1: in function '__index'
test.lua:4: in main chunk
[C]: in ?
Run Code Online (Sandbox Code Playgroud)
是否发生某种循环?为什么?
该str:method快捷方式通过__index. 通过重新定义__index,你就打破了这一点。
从5.2或5.3开始,Lua为字符串定义了一个元表,大致如下
\n\ndebug.setmetatable( "", { __index = string } )\nRun Code Online (Sandbox Code Playgroud)\n\n这允许写作("foo"):sub( i, j )。
现在你过来说
\n\ngetmetatable(\'\').__index = function(str, i) return str:sub(i, i) end\nRun Code Online (Sandbox Code Playgroud)\n\n因此,如果您说("foo")[2],则调用__index( "foo", 2 ),并在其中导致查找("foo")["sub"](在 中str:sub(i, i))。这会调用__index( "foo", "sub" ),并在其中导致查找("foo")["sub"](在 中str:sub(i, i))。这调用__index( "foo", "sub" ), 和\xe2\x80\xa6
\xe2\x80\xa6 并且堆栈溢出,因为你会("foo")["sub"]永远查找。
以您所做的方式重新定义__index意味着您不能再使用该快捷方式,这意味着您必须拼写出您使用的库代码,string.method而不是在代码中的str:method 所有位置, \xe2\x80\xa6 \xe2\x80 \x93 或者你保持它兼容。
字符索引仅对数字有意义,因此您可以通过说来获得两者
\n\ngetmetatable( "" ).__index = function( str, k )\n if type( k ) ~= "number" then return string[k] end -- lookup in string.*\n return str:sub( k, k )\nend\nRun Code Online (Sandbox Code Playgroud)\n\n这仅需要string.sub数字索引。方法名称是字符串,因此仍然会在string.