语法糖在 Lua 的元表声明中不起作用

Syntactic sugar doesn't work in metatable declaration in Lua

我正在尝试为 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 ?

是否发生了某种循环?为什么?

str:method 快捷方式通过 __index 起作用。通过重新定义 __index,您打破了它。

从 5.2 或 5.3 开始,Lua 为字符串定义了一个元表,大致类似于

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.

中查找它们