Явный '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Хотя ручная передача таблицы работает, это может казаться однообразным. В следующем уроке вы изучите более чистый синтаксис, который обрабатывает это автоматически.
Задание
ЛегкоСоздайте таблицу с именем tracker с полем count, инициализированным значением 0.
Добавьте функцию tracker.addAmount(self, amount), которая:
- Принимает
self(таблицу) в качестве первого параметра - Принимает
amountв качестве второго параметра - Добавляет
amountкself.count
Вы получите два входных значения:
- Первая сумма для добавления
- Вторая сумма для добавления
Вызовите 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)В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Object Oriented Programming
1Концепция 'self'
Таблицы с функциямиЯвный 'self'Синтаксис с двоеточиемТочка против двоеточияИтоги — Движущаяся точка4Проект: Цифровой банк
Настройка проектаМетод пополнения7Полиморфизм и переопределение
Переопределение методовВызов родительских методовУтиная типизацияОбщий интерфейсПроверка типаИтоги — Роли сотрудников2Паттерн прототипа класса
Концепция прототипаСвязывание через __indexКонструктор :new()Инициализация атрибутовНезависимые экземплярыИтоги — Автозавод5Перегрузка операторов в ООП
Сложение объектовВычитание объектовКонкатенация объектовСравнение объектов (<, >)Повторение — Математика кошелька8Инкапсуляция
Соглашения об именованииЗамыкания для приватностиДоступ через замыканияТаблицы только для чтенияЛогика валидацииИтоги — Защищенное хранилище11Паттерны проектирования (Lite)
Фабричные функцииТаблица SingletonПаттерн IteratorObserver (Слушатель)Итоги — Logger Factory3Состояние и поведение объектов
Переменные экземпляраГеттерыСеттерыВычисляемые свойстваФорматирование строкПроверка на равенствоПовторение — Оценка студента6Основы наследования
Настройка наследованияНаследование методовРасширение конструктораДобавление дочерних методовОбщее и уникальноеИтоги: Иерархия фигур