Как я могу передать эти аргументы, которые относятся к другой функции? - PullRequest
3 голосов
/ 11 июля 2019

У меня нет проблем с самим кодом. Мне просто любопытно, как это на самом деле работает.

Вот код

Vector2 = {
    x = 0, y = 0,

    mt = {},

    New = function()
        local vec = {}

        vec.x = Vector2.x
        vec.y = Vector2.y
        vec.mt = Vector2.mt
        vec.Translate = Vector2.Translate

        return vec
    end,

    Translate = function(self, dx, dy)
        self.x = self.x + dx
        self.y = self.y + dy
    end
}

v1 = Vector2.New()
v1.x = 10
v1.y = 20 
v1.Translate(v1, 10, 10)
print(v1.x, v1.y)

Этот код находится на ранней стадии. Я собираюсь узнать о мета-таблицах. Этот код может не быть умным, но я следую учебному пособию по Lua, и мне просто интересно, как это работает.

Насколько я понимаю, v1 = Vector2.New устанавливает v1 в качестве идентификатора для вызова функции New из моей таблицы.

Что я не понимаю, так это как я могу передать аргумент через v1.Translate(), который изменяет перевод?

Я бы подумал, что v1.Translate будет ссылаться на функцию New, которая не ищет всю таблицу для функции Translate.

- Обновление: это высказывание перейти к таблице Vector2, найти функцию New и запустить функцию Translate с значениями новых функций, не редактируя значения таблиц Vector2, только значения новой функции?

1 Ответ

2 голосов
/ 11 июля 2019

Здравствуйте и добро пожаловать в Stack Overflow:)

В вашем коде v1 = Vector2.New() выполнит вызов Vector2.New, и все, что возвращает эта функция, присваивается v1.

Поскольку функция Vector2.New возвращает значение vec (return vec), v1 выглядит следующим образом:

v1 = {
    x = 0, -- this is a default, because Vector2.x == 0
    y = 0, -- another default because of Vector2.y
    mt = {}, -- this is a reference to the same table in Vector2.mt
    Translate = Vector2.Translate, -- this is a function, the Vector2.Translate function, functions are first-class values in Lua
}

Поэтому, когда вы вызываете v1.Translate, вы вызываете ту же функцию, что и Vector2.Translate.

Итак, когда вы делаете v1.Translate(v1, 10, 10), вы на самом деле делаете Vector2.Translate(v1, 10, 10). Но это не из-за метатабной магии. Это потому, что вы определили v1.Translate равным Vector2.Translate.

Функции являются первоклассными значениями

Помните, что функции являются первоклассными значениями в Lua. Это означает, что вы можете передавать их, как числа, строки и таблицы.

Если вы действительно хотите, вы можете сделать это (эквивалент v1.Translate(v1, 10, 10)):

translateFn = v1.Translate
translateFn(v1, 10, 10)

Синтаксический сахар

Вместо предоставления v1 дважды в v1.Translate(v1, 10, 10), вы можете сделать это: v1:Translate(10, 10).

Когда Lua видит использование двоеточия (:) вместо точки (.), он предоставит идентификатор слева (v1) в качестве первого аргумента функции .

Он функционирует полностью так же, как и v1.Translate(v1, 10, 10), за исключением того, что v1:Translate(10, 10) в 1000 раз чище.

Это называется " синтаксический сахар ":

Синтаксический сахар - это синтаксис в языке программирования, предназначенный для облегчения чтения или выражения. Это делает язык «более сладким» для использования человеком: вещи могут быть выражены более ясно, более кратко или в альтернативном стиле, который некоторые могут предпочесть.

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...