Ошибки компилятора
Программа не собралась, и терминал выдал строки на английском. У опытных разработчиков такие сообщения появляются каждый день; разница в том, что они читают их за секунды. Этому и научимся.
Из чего состоит сообщение
Ситуация. Вы запустили программу и получили:
stagiaire@lab:~/gocourse/day01/fix1$ go run .
# day01/fix1
./main.go:9:6: undefined: fmt.println (but have Println)Как читать. Первая строка # day01/fix1 — какой пакет собирался. Вторая — сама ошибка, у неё строгий формат:
./main.go:9:6: undefined: fmt.println (but have Println)
↑ ↑ ↑ ↑
файл строка │ что не так
колонка| Кусок | Что значит |
|---|---|
./main.go |
в каком файле |
9 |
номер строки |
6 |
номер колонки — где в строке начинается проблема |
undefined: fmt.println |
текст ошибки: имя fmt.println не определено |
(but have Println) |
подсказка компилятора: зато есть Println |
Колонка считается в байтах, а не в буквах. Латинская буква, цифра, знак и табуляция — один байт, русская буква — два. Поэтому в строке с русским текстом номер колонки больше, чем число видимых символов:
./main.go:9:49: newline in stringВ строке fmt.Println("Заказов сегодня: 12) всего 33 символа, а колонка — 49. Считать до 49 не нужно: ориентируйтесь на номер строки и на то место, которое подчёркнуто в редакторе.
Номер строки виден в VS Code слева от кода. Там же ошибка подчёркнута красным, а если навести мышь — появится тот же текст. Все ошибки проекта списком — вкладка Problems, Ctrl+Shift+M. Текст одинаковый: и редактор, и терминал спрашивают один и тот же компилятор.
Порядок работы с ошибкой
- Прочитать сообщение целиком, до конца строки. Подсказка часто в самом конце — как
(but have Println). - Перейти на строку. Смотреть в указанное место, а не на весь файл.
- Сравнить с образцом. Как эта конструкция выглядела в работающей программе на третьей странице?
- Исправить одно и запустить снова.
Если сообщений несколько, начинайте с первого. Одна настоящая ошибка часто даёт несколько строк:
./main.go:9:49: newline in string
./main.go:9:49: syntax error: unexpected newline in argument list; possibly missing comma or )Строка не закрыта кавычкой, и компилятор запутался дальше. Закройте кавычку — исчезнут обе строки.
Что может пойти не так: ошибки этой недели
Все тексты ниже — настоящий вывод Go 1.27.
| Что видите | Что это значит | Как выглядит в коде | Что делать |
|---|---|---|---|
main.go:1:1: expected 'package', found 'EOF' |
файл на диске пустой: код набран в редакторе, но не сохранён | на вкладке файла белая точка | Ctrl+S — на вкладке появится крестик |
undefined: fmt.println (but have Println) |
имя написано не тем регистром | fmt.println(...) |
fmt.Println |
undefined: fmt.Printn |
опечатка в имени функции | fmt.Printn(...) |
fmt.Println |
undefined: fmt |
пакет используется, но не подключён | нет import "fmt" |
добавить import "fmt" после package main |
"os" imported and not used |
пакет подключён, но не используется — в Go это ошибка | import "os" без вызовов os. |
удалить лишний импорт |
newline in string |
строка не закрыта кавычкой до конца строки кода | fmt.Println("Привет) |
закрыть кавычку |
syntax error: unexpected EOF, expected } |
файл кончился, а фигурная скобка не закрыта | нет последней } |
закрыть скобку. EOF — end of file, конец файла |
syntax error: unexpected semicolon or newline before { |
открывающая скобка перенесена на новую строку | func main() и { на следующей строке |
{ на той же строке, что и func main() |
invalid character U+201C '“' in identifier и вторая строка про U+201D '”' |
«умные» кавычки “ ” вместо обычных " — так бывает при копировании из документов |
fmt.Println(“Привет”) |
заменить на прямые кавычки " |
more than one character in rune literal |
строка в одинарных кавычках | fmt.Println('Привет') |
двойные кавычки |
syntax error: unexpected literal 7 in argument list; possibly missing comma or ) |
нет запятой между аргументами | fmt.Println("Товаров:" 7) |
поставить запятую |
Почему скобку нельзя переносить: Go сам расставляет невидимые точки с запятой в концах строк. После func main() на отдельной строке он поставил бы её — и { на следующей строке оказалась бы оторвана от функции. Отсюда unexpected semicolon or newline before {.
Словарик ошибок
Встретили новое сообщение — запишите его. Файл ~/errors.md в домашней папке будет с вами весь курс; через месяц в нём соберётся ваш личный справочник, и большинство ошибок вы будете узнавать по первым словам.
Формат строки — текст ошибки, тире, что это значило:
undefined: fmt.println (but have Println) — написал println с маленькой буквы, функции пакета с большой
"os" imported and not used — подключил пакет, которым не пользуюсь; в Go это ошибка, а не предупреждение
newline in string — забыл закрывающую кавычку в PrintlnОткрыть файл в редакторе:
stagiaire@lab:~$ code ~/errors.mdЕсли файла нет, VS Code создаст его при первом сохранении. Проверка дня засчитывает строки не короче 20 символов, в которых между текстом ошибки и разбором стоит тире с пробелами вокруг: « — » (или « - »). Слева от тире — сообщение компилятора, латиницей, как он его напечатал; справа — разбор по-русски. Поэтому не засчитываются ни скопированная строка компилятора без разбора, ни произвольный текст с тире посередине. Файл — именно ~/errors.md в домашней папке, а не в папке дня.
Попробуйте сейчас: что выведет компилятор?
Цель: по сообщению компилятора назвать строку с ошибкой и сдать ответ.
Программа:
Код для чтения · разбираем, набирать не нужноpackage main import "fmt" func main() { fmt.Println("Север") fmt.Println(y) }Компилятор ответил:
Вывод · это печатает программа, набирать не нужно./main.go:7:14: undefined: yНа какой строке ошибка? Ответьте числом:
▶ Выполните · выделенное замените своимcourse answer day01.q3 ЧИСЛОВместо
ЧИСЛО— номер строки, на которой ошибка.Готово, когда:
course answerответилПринято: day01.q3 = …(пункт проверкиq3).
Попробуйте сейчас: почините fix1, fix2, fix3.
Цель: три программы, которые не собирались, печатают обещанное в своих комментариях, а новые сообщения записаны в словарик.
В папках
fix1,fix2,fix3лежат три программы, которые не собираются. В первых строках каждой — комментарий: что она должна напечатать. В каждой программе одна причина ошибки.1. Запустите
fix1:▶ Выполнитеcd ~/gocourse/day01/fix1 go run .2. Прочитайте сообщение по порядку работы выше: файл, строка, текст. Исправьте в
main.goодно место, сохраните, запустите снова. Когда программа напечатает то, что обещано в комментарии, переходите кfix2, потом кfix3.В
fix3компилятор выдаст три строки: одну про пакетosи две проfmt. Прочитайте все, прежде чем править: одна правка исправит все три.Правьте точечно — одну-две строки. Проверка сравнит ваш файл с оригиналом из
~/.course/orig/day01и, если программа переписана заново, пункт задания не зачтёт — даже если вывод верный. Строкиimportв этот счёт не входят: добавить или заменить пакет можно.3. Каждое новое сообщение — строкой в
~/errors.md. К концу дня в словарике должно быть минимум три разбора.▶ Выполнитеcode ~/errors.mdГотово, когда:
go run .вfix1,fix2иfix3печатает обещанное в комментарии, в каждом файле изменены одна-две строки, а в~/errors.mdне меньше трёх разборов через тире (пункты проверкиfix1,fix2,fix3,errors).
Материал дня закончен. Задания — course lab 01, дополнительное чтение — course extra 01