Перегрузка оператора Lua

Я нашел некоторые места в сети, говоря, что операторы в Lua являются сверхзагружаемыми, но я, может казаться, не нахожу примера.

Может кто-то обеспечивать пример, скажем, перегрузки + оператор для работы как.. оператор работает на конкатенацию строк?

РЕДАКТИРОВАНИЕ 1: Alexander Gladysh и RBerteig:
Если оператор, перегружающийся только, работает, когда оба операнда являются тем же типом, и изменяющий это поведение не было бы легко, то, каким образом следующий код работает? (Я не имею в виду преступления, я только что начал учить этот язык):

printf = function(fmt, ...)
    io.write(string.format(fmt, ...))
end

Set = {}
Set.mt = {}    -- metatable for sets

function Set.new (t)
    local set = {}
    setmetatable(set, Set.mt)
    for _, l in ipairs(t) do set[l] = true end
    return set
end


function Set.union (a,b)
    -- THIS IS THE PART THAT MANAGES OPERATOR OVERLOADING WITH OPERANDS OF DIFFERENT TYPES
    -- if user built new set using: new_set = some_set + some_number
    if type(a) == "table" and type(b) == "number" then
        print("building set...")
        local mixedset = Set.new{}
        for k in pairs(a) do mixedset[k] = true end
        mixedset[b] = true
        return mixedset
    -- elseif user built new set using: new_set = some_number + some_set
    elseif type(b) == "table" and type(a) == "number" then
        print("building set...")
        local mixedset = Set.new{}
        for k in pairs(b) do mixedset[k] = true end
        mixedset[a] = true
        return mixedset
    end

    if getmetatable(a) ~= Set.mt or
        getmetatable(b) ~= Set.mt then
        error("attempt to 'add' a set with a non-set value that is also not a number", 2)
    end

    local res = Set.new{}
    for k in pairs(a) do res[k] = true end
    for k in pairs(b) do res[k] = true end
    return res
end


function Set.tostring (set)
    local s = "{"
    local sep = ""
    for e in pairs(set) do
        s = s .. sep .. e
        sep = ", "
    end
    return s .. "}"
end

function Set.print (s)
    print(Set.tostring(s))
end

s1 = Set.new{10, 20, 30, 50}
s2 = Set.new{30, 1}

Set.mt.__add = Set.union

-- now try to make a new set by unioning a set plus a number:
s3 = s1 + 8
Set.print(s3)  --> {1, 10, 20, 30, 50}
10
задан PeterM 12 May 2010 в 11:13
поделиться

2 ответа

Функция metatable работает только с таблицами, но вы можете использовать debug.metatable , чтобы установить метатаблицу строк ...

> mt = {}
> debug.setmetatable("",mt)
> mt.__add = function (op1, op2) return op1 .. op2 end
> ="foo"+"bar"
foobar
> 

Другой подход - использовать debug.getmetatable для расширения метатаблицы встроенной строки (ответ на вопрос в комментарии ниже):

~ e$ lua
Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> debug.getmetatable("").__add = function (op1, op2) return op1 .. op2 end
> ="foo"+"bar"
foobar
> 
13
ответ дан 3 December 2019 в 20:40
поделиться

См. раздел Metatables руководства по программированию Lua и главу Metatables and Metamethods книги Programming in Lua 2nd edition.

Обратите внимание, что для операторов сравнения перегрузка операторов работает только когда оба типа операндов одинаковы.

5
ответ дан 3 December 2019 в 20:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: