2016-12-21 2 views

ответ

5

Да, используя «секретную» метатаблицу для строк в 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(), а другие методы не могут быть использованы с примерами, подобными этим, которые должны использоваться до изменения мета функциональности строк во всей программе.

+2

Также обратите внимание, что замена '__index' будет производить все методы по умолчанию nil. – Mossarelli

+1

Вы можете установить metatable с debug.setmetatable, хотя! – warspyking

+2

Чтобы сохранить стандартные функции: getmetatable ('') .__ index = function (str, i) return type (i) == 'number' и string.sub (str, i, i) или string [i] end' –

Смежные вопросы