2013-10-13 3 views
5

Я ищу библиотеку/функцию в lua, которая позволяет создавать пользовательские типы переменных (даже если вы определяете свой тип, используя метод типа). Я пытаюсь сделать кодировщик/декодер json, который имеет настраиваемый тип «json». Я хочу решение, которое можно выполнить только в lua.Пользовательские типы переменных Lua

ответ

9

Вы не можете создавать новые типы Lua, но вы можете имитировать их создание в значительной степени с использованием метаданных и таблиц. Например:

local frobnicator_metatable = {} 
frobnicator_metatable.__index = frobnicator_metatable 

function frobnicator_metatable.ToString(self) 
    return "Frobnicator object\n" 
     .. " field1 = " .. tostring(self.field1) .. "\n" 
     .. " field2 = " .. tostring(self.field2) 
end 


local function NewFrobnicator(arg1, arg2) 
    local obj = { field1 = arg1, field2 = arg2 } 
    return setmetatable(obj, frobnicator_metatable) 
end 

local original_type = type -- saves `type` function 
-- monkey patch type function 
type = function(obj) 
    local otype = original_type(obj) 
    if otype == "table" and getmetatable(obj) == frobnicator_metatable then 
     return "frobnicator" 
    end 
    return otype 
end 

local x = NewFrobnicator() 
local y = NewFrobnicator(1, "hello") 

print(x) 
print(y) 
print("----") 
print("The type of x is: " .. type(x)) 
print("The type of y is: " .. type(y)) 
print("----") 
print(x:ToString()) 
print(y:ToString()) 
print("----") 
print(type("hello!")) -- just to see it works as usual 
print(type({})) -- just to see it works as usual 

Выхода:

 
table: 004649D0 
table: 004649F8 
---- 
The type of x is: frobnicator 
The type of y is: frobnicator 
---- 
Frobnicator object 
    field1 = nil 
    field2 = nil 
Frobnicator object 
    field1 = 1 
    field2 = hello 
---- 
string 
table 

Конечно пример является упрощенным и есть больше вещей, чтобы сказать об объектно-ориентированном программировании в Lua. Вы можете найти следующие полезные ссылки:

+0

Для вашей функции type() здесь то, что я обычно делаю, это реализовать поле __type в метатете, которое описывает имя класса. Тогда тип всегда будет полезным значением для всех классов. – Zeksie

+0

@ Zeksie Да, это определенно вариант. Как я уже сказал, говорить о ООП в Луа гораздо больше. –

+0

Не могли бы вы создать функцию, которая создавала бы пользовательский тип переменной? Например: 'jsonCode = {" json text here "} varType (jsonCode," json ")' будет возвращать просто 'jsonCode' с пользовательским типом' 'json''. 'tostring (jsonCode)' просто вернет 'jsonCode [1]' (который в этом случае будет равен «json text здесь»). Не утруждайте себя внедрением 2-значной системы, которую вы здесь, я буду использовать ее только с таблицей, имеющей 1 значение. – tupperkion

5

То, о чем вы просите, невозможно, даже с C API. В Lua просто встроены только встроенные типы, нет возможности добавить больше. Однако, используя метаметоды и таблицы, вы можете создавать (функции создания) таблицы, которые приходят очень рядом с пользовательскими типами/классами на других языках. См. Например, Programming in Lua: Object-Oriented Programming (но имейте в виду, что книга была написана для Lua 5.0, поэтому некоторые детали могли быть изменены).

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