Да, используя «секретную» метатаблицу для строк в Lua, можно определить ряд различных операторов перегрузок для строк.
Попробуйте следующий код:
getmetatable('').__index = function(str,i) return string.sub(str,i,i) end
getmetatable('').__call = function(str,i) return string.upper(str) end
getmetatable('').__unm = function(str,i) return string.reverse(str) end
getmetatable('').__add = function(str,i) return (str .. i) end
getmetatable('').__mul = function(str,i) return string.rep(str, i) end
local str = "test"
print(str[2]) --> "e"
print(str()) --> "TEST"
print(-str) --> "tset"
print(str + "er") --> "tester"
print(str * 2) --> "testtest"
Причина вы не можете использовать setmetatable('',...)
потому, что он может быть использован только на таблицах. Но с помощью «взлома» выше вы можете легко вставлять разные методы в строки.
Помните, что используйте это локально только в своем собственном коде, если вам это действительно нужно, поскольку могут возникнуть конфликты с использованием этого проекта в глобальном масштабе.
Правильный способ управления строками или данными - использовать методы из модуля. Метаметоды, представленные в этом примере, не совместимы с ООП и влияют на все строки в области действия в Lua после того, как они были определены. Lua дает нам возможность редактировать метаданные строки, но мы должны использовать ее с ответственностью.
Нет ничего, что str:sub()
, str:upper()
, а другие методы не могут быть использованы с примерами, подобными этим, которые должны использоваться до изменения мета функциональности строк во всей программе.
Также обратите внимание, что замена '__index' будет производить все методы по умолчанию nil. – Mossarelli
Вы можете установить metatable с debug.setmetatable, хотя! – warspyking
Чтобы сохранить стандартные функции: getmetatable ('') .__ index = function (str, i) return type (i) == 'number' и string.sub (str, i, i) или string [i] end' –