我正在尝试为Python中的字符串添加索引。这有效:
getmetatable('').__index = function(str, i) return string.sub(str, i, i) end
str1 = 'hello'
print(str1[1])
这不是:
getmetatable('').__index = function(str, i) return str:sub(i, i) end
发出以下错误:
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 ?
是否有某种循环发生?为什么呢?
答案 0 :(得分:4)
str:method
快捷方式可通过__index
运行。通过重新定义__index
,你可以打破它。
自5.2或5.3以来,Lua为字符串定义了一个metatable,大致类似于
debug.setmetatable( "", { __index = string } )
允许撰写("foo"):sub( i, j )
。
现在你过来说
getmetatable('').__index = function(str, i) return str:sub(i, i) end
所以,如果您说("foo")[2]
,那就会调用__index( "foo", 2 )
,而这会导致查找("foo")["sub"]
(在str:sub(i, i)
中)。这会调用__index( "foo", "sub" )
,并在其中导致查找("foo")["sub"]
(在str:sub(i, i)
中)。这会调用__index( "foo", "sub" )
和...
...并且堆栈溢出,因为您永远查找("foo")["sub"]
。
以您的方式重新定义__index
意味着您无法再使用该快捷方式,这意味着您必须拼出string.method
而不是str:method
代码中的无处不在,您使用的库代码,...... - 或者您保持兼容。
字符索引仅对数字有意义,因此您可以通过说
来获得两者getmetatable( "" ).__index = function( str, k )
if type( k ) ~= "number" then return string[k] end -- lookup in string.*
return str:sub( k, k )
end
这只会为string.sub
调用数字索引。方法名称是字符串,因此仍然会在string
中查找它们。