Пустота: null
Значения нет — и это тоже значение. Главный источник молчаливых ошибок в mlog
null — не ноль, не ошибка и не пустая строка. Это ответ «значения нет»: спросили —
а сказать нечего.
Отдельный урок ему нужен потому, что с ним сталкиваются все и постоянно, а ведёт он себя
незаметно: программа с null не падает и не жалуется, она просто считает не то.
Откуда он берётся
Заголовок раздела «Откуда он берётся»| Случай | Пример |
|---|---|
| переменную ни разу не записали | опечатка в имени, чужое имя |
sensor у блока, которого нет |
связь снесли, а программа спрашивает |
sensor неприменимого свойства |
жидкость у хранилища, @totalItems у типа блока |
getlink за пределом числа связей |
перебрали больше, чем есть |
@unit до ubind и после гибели юнита |
юнита сбили посреди работы |
| чтение памяти за границей ячейки | адрес 64 в ячейке на 64 значения |
| вычисление без ответа | деление на ноль, корень из минуса, логарифм нуля |
Последняя строка удивляет чаще всего: в mlog нет ни бесконечности, ни NaN. Всё, что
математика не смогла посчитать, становится пустотой.
В арифметике это ноль
Заголовок раздела «В арифметике это ноль»Нажмите «шаг» шесть раз. null в числовом контексте — ноль, любой другой объект — единица:
equal равно безЗначения 0— 1;add сумма безЗначения 1— 1;add объектПлюсОдин @copper 1— 2, медь как объект это единица;strictEqual строго безЗначения 0— 0, и вот это самое важное.
Отличить пустоту от нуля умеет только строгое сравнение
Заголовок раздела «Отличить пустоту от нуля умеет только строгое сравнение»Обычные equal и notEqual смотрят на число, а число у пустоты — ноль. Строгое сравнение
смотрит ещё и на вид значения, поэтому только оно видит разницу.
В справочниках и в тексте программы оно называется strictEqual, а в блоке подписано
знаком === — искать в списке нужно именно его. Знаки в игре не переводятся, так что
=== останется === при любом языке.
| Нужно | Чем |
|---|---|
| сохранить ответ в переменную | op strictEqual пусто ответ null |
| свернуть в сторону | jump strictEqual на ветку «данных нет» |
| выбрать одно из двух значений | select с тем же условием |
Чем это кусается
Заголовок раздела «Чем это кусается»Обычная проверка «в блоке кончилась медь» — это два блока: sensor спрашивает у хранилища
@copper, jump сравнивает ответ с нулём.
Отсюда правило: проверяйте на null раньше, чем на ноль. Порядок строк такой:
sensor— запросить@copperу хранилища;op strictEqual— сравнить ответ сnull;jump— если сравнение дало единицу, уйти на «блока нет»;- и только теперь сравнивать с нулём.
Два лишних блока в начале — цена за то, что программа отличает «кончилось» от «сломалось». Ставить их стоит везде, где данные приходят снаружи: от связей, от юнитов, из памяти.
Неофициальный проект, с Anuke не связан. Спрайты, шрифты и переводы Mindustry © Anuke, используются по GPL-3.0; Fira Code — по OFL-1.1. Код сайта — GPL-3.0.