Ошибки компиляции
В первом уроке компилятор был строгим корректором: он читает рецепт целиком, прежде чем на кухне начнут готовить. Посмотрим, что он делает, когда находит ошибку, и как читать его пометки.
Вот программа из двух строк. Первая написана верно, а во второй опечатка — prnt вместо print:
print("Hello!")
prnt("Hi") // ✗error: cannot find 'prnt' in scopeПрограмма не напечатала ничего — даже Hello!, хотя первая строка верна. Давайте разберём, почему так вышло:
- Компилятор проверяет весь файл ещё до того, как выполнится первая строка.
- Во второй строке он находит имя
prnt, которого в Swift нет. - Готовую программу он не создаёт и сообщает об ошибке.
- Запускать нечего, поэтому не выполняется ни одна строка — и верная тоже.
Такая ошибка называется ошибкой компиляции: её находит компилятор до запуска, а не работающая программа. Корректор вернул рецепт целиком, и на кухне не выполнили ни одного шага, даже правильного.
Когда находят ошибку
На собеседовании любят спрашивать: во второй строке опечатка — успеет ли выполниться первая? В Swift ответ — нет. Программа с ошибкой компиляции не запускается вовсе, поэтому первая строка ничего не напечатает.
В некоторых других языках программа начинает работать без проверки всего текста. Там ошибку вроде этой находят, только когда выполнение дойдёт до её строки. Поэтому первая строка нашей программы успела бы напечатать текст. Swift устроен иначе: сначала компилятор проверяет весь файл, и только потом программа запускается.
Язык, в котором компилятор целиком переводит текст перед запуском, называют компилируемым. Swift — компилируемый язык.
Как читать сообщение
Компилятор пишет, где ошибка и что не так. Целиком первая строка сообщения выглядит так: main.swift:2:1: error: cannot find 'prnt' in scope. Давайте разберём её слева направо:
main.swift— имя файла.2— номер строки.1— номер символа в этой строке:prntначинается с первого символа.error— вид сообщения: ошибка.cannot find 'prnt' in scope— что не так: в этом месте программы нет ничего с именемprnt.
Под первой строкой сообщения Swift повторяет кусок программы вокруг ошибки и отмечает место, где её заметил. В Xcode то же сообщение появляется рядом со строкой.
Все ошибки сразу
Корректор отмечает все ошибки рецепта за один раз. Компилятор тоже проверяет файл целиком и перечисляет все ошибки, которые нашёл:
print("Start")
prnt("Hi") // ✗
pritn("End") // ✗error: cannot find 'prnt' in scope
error: cannot find 'pritn' in scopeКаждое сообщение называет свою строку: вторую и третью. Исправляйте ошибки по порядку, сверху вниз, и компилируйте снова. Бывает, что следующие ошибки в списке исчезают вместе с первой. Бывает и наоборот: часть проверок компилятор делает, только когда исправлены первые ошибки, и тогда в списке появляются новые.
Предупреждения
Кроме ошибок компилятор выдаёт предупреждения. С предупреждением программа компилируется и запускается, но компилятор отмечает подозрительное место. Это как пометка «проверьте» на полях: корректор всё равно отправляет рецепт на кухню.
print("Start") // Start
"Hello!" // ✗
print("End") // Endwarning: string literal is unusedВо второй строке забыли написать print. Текст "Hello!" стоит отдельно, и с ним ничего не делается. Давайте посмотрим, что получилось:
- Компилятор нашёл подозрительную строку и выдал предупреждение: «текст в кавычках не используется».
- Ошибок нет, поэтому программа собралась и запустилась.
- Она напечатала
StartиEnd, аHello!— нет.
Здесь картинка с корректором снова неточна. Корректор догадался бы, что в строке пропущено слово print. Компилятор замысла автора не знает и сообщает только то, что видит: текст в кавычках ни для чего не используется.
Сообщение начинается со слова warning, а не error. В терминале в конце этой строки стоит ещё пометка [#NoUsage] — имя страницы справки о таком предупреждении. Под сообщением компилятор печатает ссылку на эту страницу. Предупреждение не мешает запуску, но читать его стоит: часто оно указывает на настоящий промах, как здесь.
Частая ошибка
Две команды записаны на одной строке:
print("one") print("two") // ✗error: consecutive statements on a line must be separated by ';'Программа не компилируется. Сообщение говорит: команды, которые идут подряд на одной строке, нужно разделять точкой с запятой. Две команды через точку с запятой Swift примет, но так писать не принято: перенесите второй print на новую строку.
Главное
- Компилятор проверяет весь файл до запуска: при ошибке компиляции программа не запускается, и не выполняется ни одна строка.
- Сообщение называет файл, строку и символ, затем вид —
errorилиwarning— и что не так. - Компилятор перечисляет все ошибки, которые нашёл; исправляйте их сверху вниз и компилируйте снова: после исправления могут появиться новые.
- С предупреждением программа работает, но оно часто указывает на настоящий промах.