Menu
Coddy logo textTech

Явный 'self'

Часть раздела Object Oriented Programming путешествия по Lua на Coddy — урок 2 из 70.

Когда функция находится внутри таблицы, ей часто требуется доступ к данным или их изменение внутри этой же таблицы. Но вот в чем проблема: как функция узнает, к какой таблице она относится?

Решение состоит в том, чтобы явно передать таблицу в качестве первого аргумента функции. По соглашению этот параметр называется self:

local counter = {
    value = 0
}

function counter.increment(self)
    self.value = self.value + 1
end

counter.increment(counter)
print(counter.value)  -- Вывод: 1

Обратите внимание, как мы вызываем counter.increment(counter), передавая саму таблицу в качестве аргумента. Внутри функции self теперь ссылается на эту таблицу, позволяя нам читать и изменять self.value.

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

function counter.reset(self)
    local old = self.value
    self.value = 0
    return old
end

print(counter.reset(counter))  -- Вывод: 1
print(counter.value)           -- Вывод: 0

Хотя ручная передача таблицы работает, это может казаться однообразным. В следующем уроке вы изучите более чистый синтаксис, который обрабатывает это автоматически.

challenge icon

Задание

Легко

Создайте таблицу с именем tracker с полем count, инициализированным значением 0.

Добавьте функцию tracker.addAmount(self, amount), которая:

  • Принимает self (таблицу) в качестве первого параметра
  • Принимает amount в качестве второго параметра
  • Добавляет amount к self.count

Вы получите два входных значения:

  1. Первая сумма для добавления
  2. Вторая сумма для добавления

Вызовите tracker.addAmount дважды (по одному разу для каждого входного значения), каждый раз передавая таблицу в качестве первого аргумента. После обоих вызовов выведите конечное значение tracker.count.

Шпаргалка

Функции внутри таблиц могут получать доступ к данным таблицы, принимая таблицу в качестве своего первого параметра, который по соглашению называется self:

local counter = {
    value = 0
}

function counter.increment(self)
    self.value = self.value + 1
end

counter.increment(counter)  -- Pass the table as argument
print(counter.value)  -- Output: 1

Параметр self позволяет функции читать и изменять поля таблицы без жесткого кодирования имени таблицы:

function counter.reset(self)
    local old = self.value
    self.value = 0
    return old
end

print(counter.reset(counter))  -- Output: 1
print(counter.value)           -- Output: 0

Функции могут принимать дополнительные параметры после self:

function counter.add(self, amount)
    self.value = self.value + amount
end

counter.add(counter, 5)

Попробуйте сами

-- Чтение входных данных
local amount1 = tonumber(io.read())
local amount2 = tonumber(io.read())

-- TODO: Напишите ваш код ниже
-- Создайте таблицу с именем 'tracker' с полем 'count', инициализированным значением 0
-- Добавьте функцию tracker.addAmount(self, amount), которая добавляет amount к self.count
-- Вызовите tracker.addAmount дважды, передав таблицу в качестве первого аргумента


-- Вывод итогового значения count
print(tracker.count)
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Object Oriented Programming