Перейти к содержимому

Пустота: null

Значения нет — и это тоже значение. Главный источник молчаливых ошибок в mlog

среднийНужно знать: Число, объект и текст

null — не ноль, не ошибка и не пустая строка. Это ответ «значения нет»: спросили — а сказать нечего.

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

Случай Пример
переменную ни разу не записали опечатка в имени, чужое имя
sensor у блока, которого нет связь снесли, а программа спрашивает
sensor неприменимого свойства жидкость у хранилища, @totalItems у типа блока
getlink за пределом числа связей перебрали больше, чем есть
@unit до ubind и после гибели юнита юнита сбили посреди работы
чтение памяти за границей ячейки адрес 64 в ячейке на 64 значения
вычисление без ответа деление на ноль, корень из минуса, логарифм нуля

Последняя строка удивляет чаще всего: в mlog нет ни бесконечности, ни NaN. Всё, что математика не смогла посчитать, становится пустотой.

тик 0
Установить0
=
Операция1
=
Операция2
=
Операция3
=
Установить4
=
Операция5
=
@counter0number
безЗначенияnullnull
равноnullnull
строгоnullnull
суммаnullnull
предметnullnull
объектПлюсОдинnullnull

Нажмите «шаг» шесть раз. null в числовом контексте — ноль, любой другой объект — единица:

  • equal равно безЗначения 01;
  • add сумма безЗначения 11;
  • add объектПлюсОдин @copper 12, медь как объект это единица;
  • strictEqual строго безЗначения 00, и вот это самое важное.

Отличить пустоту от нуля умеет только строгое сравнение

Заголовок раздела «Отличить пустоту от нуля умеет только строгое сравнение»

Обычные equal и notEqual смотрят на число, а число у пустоты — ноль. Строгое сравнение смотрит ещё и на вид значения, поэтому только оно видит разницу.

В справочниках и в тексте программы оно называется strictEqual, а в блоке подписано знаком === — искать в списке нужно именно его. Знаки в игре не переводятся, так что === останется === при любом языке.

Нужно Чем
сохранить ответ в переменную op strictEqual пусто ответ null
свернуть в сторону jump strictEqual на ветку «данных нет»
выбрать одно из двух значений select с тем же условием

Обычная проверка «в блоке кончилась медь» — это два блока: sensor спрашивает у хранилища @copper, jump сравнивает ответ с нулём.

Отсюда правило: проверяйте на null раньше, чем на ноль. Порядок строк такой:

  1. sensor — запросить @copper у хранилища;
  2. op strictEqual — сравнить ответ с null;
  3. jump — если сравнение дало единицу, уйти на «блока нет»;
  4. и только теперь сравнивать с нулём.

Два лишних блока в начале — цена за то, что программа отличает «кончилось» от «сломалось». Ставить их стоит везде, где данные приходят снаружи: от связей, от юнитов, из памяти.

Неофициальный проект, с Anuke не связан. Спрайты, шрифты и переводы Mindustry © Anuke, используются по GPL-3.0; Fira Code — по OFL-1.1. Код сайта — GPL-3.0.