День 01 · Программа, терминал, первый запуск · страница 3 из 6

Первая программа

Напишем программу, которая печатает строчку текста, и разберём её по словам. Каждое слово в ней будет в каждой программе курса.


Где живёт программа

Программа на Go живёт в модуле — папке, в которой лежит файл go.mod. Модуль — граница проекта: команды go ищут go.mod в текущей папке и выше, и всё, что внутри, считают частью одного проекта.

Модуль дня уже создан — это ~/gocourse/day01. Загляните в его go.mod:

Пример · только посмотреть, набирать не нужно
stagiaire@lab:~$ cd ~/gocourse/day01
stagiaire@lab:~/gocourse/day01$ cat go.mod
module day01

go 1.27

Как читать. module day01 — имя модуля. go 1.27 — на какую версию языка он рассчитан. Больше в нём сегодня ничего нет, и трогать его не нужно. cat — команда, которая печатает содержимое файла.

Внутри модуля каждое задание — своя папка: hello, receipt, fix1. В каждой папке — своя программа.


Открыть модуль в редакторе

Писать код удобнее в VS Code, который вы настроили в день 0. Откройте в нём папку модуля — не отдельный файл:

Пример · только посмотреть, набирать не нужно
stagiaire@lab:~/gocourse/day01$ code .

Точка означает «текущая папка». Редактор откроется, слева в панели Explorer будут видны папки заданий. Если VS Code спросит, доверяете ли вы авторам файлов, — ответьте Yes, I trust the authors, иначе расширение Go отключится.

Почему именно папка модуля: редактор понимает Go-код только вместе с go.mod. Открытый сам по себе файл он не свяжет с модулем, и половина подсказок пропадёт.


Пишем

Попробуйте сейчас: создайте hello/main.go.

Цель: в папке hello лежит сохранённый файл main.go с первой программой.

1. В Explorer щёлкните по папке hello, чтобы она выделилась, затем нажмите значок New File в заголовке панели EXPLORER и назовите файл main.go. Проверьте, что main.go появился под hello, а не рядом с go.mod.

Запасной путь — из терминала:

▶ Выполните
cd ~/gocourse/day01/hello
code main.go

Редактор откроет новый файл, на диске он появится при первом сохранении.

2. Напечатайте — именно напечатайте руками:

✎ Наберите в файл hello/main.go
package main

import "fmt"

func main() {
	fmt.Println("Привет, мир!")
}

3. Сохраните: Ctrl+S. Пока в файле есть несохранённые изменения, на его вкладке вместо крестика белая точка.

Готово, когда: main.go виден в Explorer под hello, а на его вкладке крестик, а не белая точка.


Запускаем

Попробуйте сейчас: запустите hello.

Цель: программа из папки hello напечатала строку Привет, мир!.

В терминале — в обычном или во встроенном в VS Code (Ctrl+` ) — из папки модуля ~/gocourse/day01 перейдите в папку программы и запустите:

▶ Выполните
cd hello
go run .

Что должно получиться:

Вывод · это печатает программа, набирать не нужно
Привет, мир!

Готово, когда: под go run . появилась строка Привет, мир! (пункт проверки t_gorun).

go run . — «собери программу из этой папки и сразу запусти». Точка — та же «текущая папка». Первый запуск может занять пару секунд: компилятор переводит программу. Строка Привет, мир! — то, что напечатала ваша программа.


Как это читать — по строкам

Строка Что значит
package main файл относится к пакету main. Пакет — группа файлов одной папки. Имя main особое: только из такого пакета получается программа, которую можно запустить
пустая строка для глаз; компилятору всё равно
import "fmt" подключить пакет fmt из стандартной библиотеки Go. В нём функции для печати на экран. Название — от format
func main() { объявление функции main. Функция — именованный кусок кода. С функции main программа начинает выполняться. Фигурная скобка { открывает её тело
fmt.Println("Привет, мир!") вызвать функцию Println из пакета fmt и передать ей текст. Println — print line: напечатать и перейти на новую строку
} тело main закончилось — программа завершилась

Три детали, на которых чаще всего спотыкаются:


Команды выполняются сверху вниз

Добавьте в main вторую строку — тело функции станет таким:

Код для чтения · разбираем, набирать не нужно
func main() {
	fmt.Println("Привет, мир!")
	fmt.Println("Я пишу на Go.")
}

Здесь показаны только строки функции main: package main и import "fmt" в файле остаются на месте. Файл целиком — в блоке ниже.

Пример · только посмотреть, набирать не нужно
stagiaire@lab:~/gocourse/day01/hello$ go run .
Привет, мир!
Я пишу на Go.

Программа выполняет строки тела main по порядку, одну за другой. Поменяете строки местами — поменяется порядок вывода. Это правило кажется очевидным, но именно его нарушают, когда читают чужой код «по диагонали».


Формат кода

В Go один принятый формат кода на всех: отступы табуляцией, пробелы вокруг знаков, скобки на своих местах. Расставляет его программа gofmt. В VS Code она срабатывает сама при каждом Ctrl+S. В терминале:

Пример · только посмотреть, набирать не нужно
stagiaire@lab:~/gocourse/day01/hello$ gofmt -l .
stagiaire@lab:~/gocourse/day01/hello$ gofmt -w main.go

gofmt -l . печатает имена файлов, которые не отформатированы. Пустой вывод — всё в порядке. gofmt -w main.go переформатирует файл на месте. Спорить о расстановке пробелов в Go не принято: как сделал gofmt, так и правильно.


Что может пойти не так

Что видите Что это значит Что делать
go: go.mod file not found in current directory or any parent directory; see 'go help modules' вы не внутри модуля — например, в домашней папке cd ~/gocourse/day01/hello
no Go files in /home/stagiaire/gocourse/day01 вы в папке модуля, а программа лежит в папке hello cd hello
package day01/hello is not a main package первая строка файла не package main исправить первую строку
runtime.main_main·f: function main is undeclared in the main package нет функции main — чаще всего опечатка в имени: mian, Main имя функции ровно main, маленькими буквами
main.go:1:1: expected 'package', found 'EOF' файл на диске пустой: код набран в редакторе, но не сохранён Ctrl+S — на вкладке белая точка сменится крестиком, потом снова go run .
изменили текст, а печатается старый то же самое: не сохранили Ctrl+S

Попробуйте сейчас: доведите hello до двух строк.

Цель: hello печатает такой вывод — ровно две строки, с запятой, восклицательным знаком и точкой:

Вывод · это печатает программа, набирать не нужно
Привет, мир!
Я пишу на Go.

1. Файл hello/main.go целиком:

✎ Наберите в файл hello/main.go
package main

import "fmt"

func main() {
	fmt.Println("Привет, мир!")
	fmt.Println("Я пишу на Go.")
}

2. Сохраните (Ctrl+S) и запустите:

▶ Выполните
cd ~/gocourse/day01/hello
go run .
gofmt -l .

gofmt -l . должен ничего не напечатать. Это первое задание дня — проверка сверит вывод буква в букву.

Готово, когда: go run . печатает эти две строки буква в букву, а gofmt -l . — ничего (пункты проверки hello_build, hello_out, hello_fmt).


Попробуйте сейчас: что выведет?

Цель: предсказать вторую строку вывода, не запуская программу, и сдать ответ.

1. Не запуская, предскажите, что напечатает программа:

Код для чтения · разбираем, набирать не нужно
package main

import "fmt"

func main() {
	fmt.Println("Раз")
	fmt.Println("Два", "Три")
}

Подсказка к синтаксису: в скобках Println может стоять несколько значений через запятую — он напечатает их в одной строке, разделив пробелом. Подробно об этом — на пятой странице.

2. Отправьте, что будет во второй строке вывода:

▶ Выполните · выделенное замените своим
course answer day01.q1 ВАШ_ОТВЕТ

Вместо ВАШ_ОТВЕТ — вторая строка вывода, как вы её предсказали.

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

3. После ответа проверьте себя запуском. Создайте папку для опытов:

▶ Выполните
mkdir -p ~/gocourse/day01/scratch

Теперь ту же программу нужно набрать — в scratch/main.go:

✎ Наберите в файл scratch/main.go
package main

import "fmt"

func main() {
	fmt.Println("Раз")
	fmt.Println("Два", "Три")
}

Запустите:

▶ Выполните
cd ~/gocourse/day01/scratch
go run .

Если вывод разошёлся с вашим ответом — перечитайте раздел «Как это читать» выше.

Готово, когда: course answer ответил Принято: day01.q1 = … (пункт проверки q1).


Дальше: что именно делает go run и чем от него отличается go build — course next