Перейти к содержимому
Теория · Первая программа · урок 2 из 8

Ошибки компиляции

В прошлом уроке компилятор был строгим корректором, который не пускает рецепт с ошибкой на кухню. Теперь посмотрим, как он сообщает о том, что нашёл, и какие правила Go проверяет строже других языков.

Go не собирает программу, которая объявляет переменную внутри функции и не использует её. Строка n := 10 создаёт переменную n — имя, под которым хранится значение 10. Дальше программа её не читает:

GO
package main

import "fmt"

func main() {
    n := 10 // ✗
    fmt.Println("ok")
}
TEXT
declared and not used: n

Это ошибка компиляции: компилятор отказался переводить текст, поэтому программа ни разу не запустилась. Слово ok тоже не напечатано, хотя строка с ним написана верно. Корректор вернул рецепт целиком, и на кухне не выполнили ни одного шага, даже правильного.

Сообщение компилятора

Корректор возвращает рукопись с пометками на полях: где ошибка и что не так. Компилятор делает то же самое. Целиком сообщение выглядит так: ./main.go:6:5: declared and not used: n.

Давайте разберём его по частям, слева направо:

  1. ./main.go — имя файла.
  2. 6 — номер строки.
  3. 5 — номер символа в этой строке: в шестой строке после четырёх пробелов отступа стоит n.
  4. declared and not used: n — после последнего двоеточия компилятор пишет, что именно нарушено.

Если ошибок несколько, компилятор перечисляет их по одной на строку. Исправляйте их сверху вниз: следующие в списке иногда исчезают вместе с первой.

Две команды сборки

Собрать программу можно двумя командами. Они по-разному обходятся с результатом, поэтому разберём каждую отдельно.

go build — только сборка

Команда go build main.go состоит из трёх частей:

  • go — инструмент, который устанавливается вместе с языком;
  • build — действие «собрать»;
  • main.go — файл с программой.

Без ошибок команда создаёт готовую программу в папке, из которой её запустили. Файл называется как исходный файл без .go: из main.go получается main, а в Windows — main.exe.

Программу запускают отдельно и сколько угодно раз, без новой компиляции. При ошибке компиляции команда не создаёт файл программы.

go run — сборка и запуск

Команда go run main.go компилирует программу так же, как go build, и сразу запускает результат. Готовый файл программы в папке при этом не появляется.

Эта команда удобна, пока вы пишете программу и проверяете, что она печатает: один шаг вместо двух. При ошибке компиляции она ничего не запускает.

Ошибки вместо предупреждений

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

У корректора Go так не бывает: в Go предупреждений нет, и всё, что находит компилятор, — ошибка. Неиспользуемая переменная — одна из таких ошибок. Она часто выдаёт промах автора: значение посчитали, но забыли напечатать или передать дальше.

Этот вопрос часто задают на собеседовании: что будет, если объявить переменную и ни разу её не прочитать? Обычно звучат три ответа:

  • «программа не скомпилируется» — верно;
  • «напечатает предупреждение» — неверно: предупреждений в Go нет;
  • «упадёт при запуске» — неверно: до запуска дело не дойдёт.

Два способа исправить

Неиспользуемую переменную можно исправить двумя способами. Выбор зависит от того, нужно ли программе её значение.

Прочитать переменную

Если значение нужно, используйте его — например, напечатайте:

GO
package main

import "fmt"

func main() {
    n := 10
    fmt.Println(n) // 10
}

Теперь n используется: fmt.Println(n) читает переменную и печатает 10. Компилятору больше не к чему придраться, и программа запускается.

Удалить строку

Если значение не нужно, удалите строку n := 10 целиком. В первом примере после этого остаётся только fmt.Println("ok"), и программа печатает ok.

Частая ошибка

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

GO
package main

import "fmt" // ✗

func main() {
}
TEXT
"fmt" imported and not used

Чтобы исправить ошибку, удалите строку import "fmt": вызовов из пакета fmt в программе не осталось.

Главное

  • Ошибка компиляции останавливает сборку: программа не запускается, и не выполняется ни одна строка.
  • Сообщение называет файл, строку и символ, а после последнего двоеточия — нарушенное правило.
  • В Go нет предупреждений: неиспользуемая переменная внутри функции и неиспользуемый импорт — ошибки.
  • go build только компилирует программу, а go run компилирует и сразу запускает.

Подпишись, чтобы пройти курс

Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.

Войти другим способом