Синтаксис и пунктуация в Go
Названия знаков по-английски и по-русски: Знаки препинания и символы в IT.
Общие принципы
Go использует небольшой набор знаков препинания: синтаксис близок к C, без "магии" вроде ASI в JavaScript. При этом компилятор автоматически вставляет ; в конце строк по лексическим правилам (automatic semicolon insertion), поэтому в обычном коде точку с запятой почти не пишут вручную.
Кавычки и строки
Двойные кавычки "
Строковый литерал — последовательность байт (UTF-8). Экранирование как в C — \n, \t, \".
name := "Alice"
message := "Привет, мир!"
path := "C:\\Users\\dev" // обратный слэш экранируется
Разбор:
:=создаёт новую переменную с выводом типа из правой части, поэтомуname,messageиpathполучают типstring.- Литералы в двойных кавычках поддерживают escape-последовательности, поэтому
\\превращается в один символ\в итоговой строке. - Комментарий после
//игнорируется компилятором и служит только для объяснения, почему здесь двойной слэш. - Все три значения хранятся как неизменяемые строки UTF-8; изменение такого значения всегда создаёт новую строку.
Интерполяции внутри строк нет — для подстановки значений используют fmt.Sprintf или конкатенацию.
fmt.Printf("Hello, %s\n", name)
Разбор:
fmt.Printfформатирует строку по шаблону:%sожидает строковый аргумент, а\nдобавляет перевод строки в конце вывода.- Параметр
nameподставляется в позицию%s, поэтому шаблон и список аргументов должны совпадать по типам и количеству. - Функция печатает результат в стандартный вывод (
stdout), что удобно для консольных программ и отладки. - Такой вызов заменяет интерполяцию строк, которая в Go синтаксически отсутствует.
Обратные кавычки `
Raw-строка: переносы строк и обратные слэши сохраняются как есть. Удобно для regex, путей Windows, многострочных шаблонов.
doc := `SELECT *
FROM users
WHERE id = 1`
Разбор:
- Обратные кавычки создают raw-строку: переносы строк и спецсимволы внутри сохраняются буквально, без экранирования.
- Переменная
docхранит многострочный SQL-текст в том же виде, как он написан в исходнике. - Такой формат удобен для шаблонов, SQL и регулярных выражений, где обычные escape-последовательности перегружают запись.
- В raw-строке нельзя использовать сам символ обратной кавычки без дополнительных приёмов.
Одинарные кавычки '
Только для литерала rune (int32, кодовая точка Unicode), не для текста.
var letter rune = 'A'
var emoji rune = '🙂' // в исходнике файл должен быть UTF-8
Разбор:
rune— это алиасint32, который хранит кодовую точку Unicode, а не строку.- Литерал в одинарных кавычках должен содержать один символ (одну кодовую точку), поэтому
'A'и'🙂'корректны. - Для emoji в исходнике важна кодировка UTF-8, чтобы компилятор корректно прочитал символ.
- Такие значения удобно использовать при посимвольной обработке текста и сравнении отдельных символов.
Попытка написать 'hello' — ошибка компиляции: ожидается один символ.
"Умные" апострофы
Символы ' и ' из текстовых редакторов не являются синтаксисом Go. Компилятор выдаст ошибку — в коде только ASCII-кавычки ' и ".
title := "Go Developer's Guide"
quote := "He said: \"Go is simple\""
Разбор:
- Апостроф внутри строки (
Developer's) не требует экранирования, так как строка ограничена двойными кавычками. - Внутренние двойные кавычки в
quoteэкранируются через\", иначе строковый литерал завершится раньше времени. - Такой пример показывает практическую разницу между обычными символами текста и синтаксическими ограничителями строки.
- Результирующие значения остаются обычными
stringи могут дальше передаваться вfmt.Println, JSON и шаблоны.
Точка .
Точка — доступ к полю структуры или методу (в том числе экспортированному, если имя с заглавной буквы):
type Point struct{ X, Y int }
p := Point{X: 5, Y: 10}
fmt.Println(p.X)
Разбор:
type Point struct{ X, Y int }объявляет структуру с двумя полями типаint.- Литерал
Point{X: 5, Y: 10}создаёт экземпляр структуры с явным присваиванием по именам полей. p.Xиспользует точечный доступ к полю структуры; это базовый механизм обращения к данным объекта в Go.fmt.Printlnвыводит значение поля в консоль и автоматически добавляет перевод строки.
Цепочки вызовов:
strings.TrimSpace(strings.ToLower(s))
Разбор:
- Внутренний вызов
strings.ToLower(s)сначала переводит строкуsв нижний регистр. - Результат этого вызова передаётся во внешний
strings.TrimSpace(...), который убирает пробелы по краям. - Такой вложенный стиль показывает композицию функций: каждая решает маленькую задачу, итог строится цепочкой.
- Исходная строка не меняется, потому что строки в Go неизменяемы.
Запятая ,
Разделяет:
- аргументы функции и параметры в объявлении;
- элементы среза и литерала структуры;
- имена в
import,const,var(многострочные блоки).
nums := []int{1, 2, 3}
func greet(name string, age int) {}
Разбор:
[]int{1, 2, 3}создаёт слайс целых чисел с тремя элементами; запятые разделяют элементы литерала.- В объявлении
func greet(name string, age int)запятая разделяет параметры функции. - Тип каждого параметра указывается после имени, что является стандартным синтаксисом Go.
- Пустое тело
{}означает, что функция сейчас только демонстрирует сигнатуру без логики.
В многострочных литералах завершающая запятая после последнего элемента разрешена и часто рекомендуется — так проще добавлять строки в diff:
return []string{
"first",
"second", // trailing comma OK
}
Разбор:
- Возвращается литерал слайса строк
[]string{...}прямо из функции без промежуточной переменной. - Запятая после последнего элемента в многострочной форме считается корректной и полезной для стабильных diff.
- Комментарий
trailing comma OKподчёркивает, что это осознанная идиома Go-кода. - Такой стиль уменьшает шум при добавлении новых элементов в конце списка.
Точка с запятой ;
Вручную ставят в основном в заголовке цикла for:
for i := 0; i < 10; i++ {
fmt.Println(i)
}
Разбор:
- Это классический
forс тремя частями — инициализацияi := 0, условиеi < 10, шагi++. - На каждой итерации
fmt.Println(i)печатает текущее значение счётчика. - Цикл завершится, когда условие станет ложным (
iдостигнет10). - В Go это одна из форм единственного циклического оператора
for.
В остальных строках компилятор вставляет ; сам. Явные ; в конце строк допустимы, но не приняты в идиоматичном стиле.
Скобки
| Символ | Назначение |
|---|---|
() | Вызов функции, группировка, условие if/for |
{} | Тело функции, блок; обязательны даже для одной строки |
[] | Срез, массив, индекс |
if x > 0 {
fmt.Println("positive")
}
Разбор:
- Условие
x > 0должно иметь типbool; неявные преобразования к булеву типу в Go отсутствуют. - Фигурные скобки обязательны даже для одной команды в теле
if. - При истинном условии выполняется вызов
fmt.Println("positive"). - Такой явный блочный синтаксис снижает риск ошибок при расширении ветки.
Отсутствие фигурных скобок у if — синтаксическая ошибка (в отличие от C или JavaScript).
Подчёркивание _
_как имя — значение отбрасывается (импорт только ради побочного эффекта, игнор возвращаемого значения).- В числах
1_000_000— разделитель для читаемости (с Go 1.13). - Не экспортируемые идентификаторы начинаются со строчной буквы; подчёркивание в начале имени не делает поле "приватным" — приватность определяется регистром первой буквы пакета.
_, err := fmt.Println("ok")
const billion = 1_000_000_000
Разбор:
_— пустой идентификатор: он принимает значение и сразу его отбрасывает, чтобы не хранить ненужный результат.err := ...сохраняет только ошибку из множественного возвратаfmt.Println.1_000_000_000использует подчёркивания как визуальные разделители разрядов без изменения численного значения.- Такой стиль повышает читаемость больших чисел и помогает избегать ошибок при ручном вводе.
Двоеточие :
В объявлениях с коротким синтаксисом:
name := "Go" // новая переменная
for i, v := range slice {}
switch x := v.(type) {}
Разбор:
name := "Go"создаёт новую локальную переменную с типомstring.for i, v := range sliceодновременно объявляет индексiи копию элементаvпри проходе по слайсу.switch x := v.(type)демонстрирует type-switch:xполучает конкретный динамический тип из интерфейсного значения.- Во всех трёх конструкциях
:=совмещает объявление переменных и начальную инициализацию.
Типичные ошибки
- Строка в одинарных кавычках — нужны двойные или raw.
- Забыть
{}уif— в Go блок всегда в фигурных скобках. - Смешать rune и string при сравнении — явное преобразование
string(r). - Неиспользуемый импорт или переменная — компилятор не соберёт проект (в отличие от многих языков).
var r rune = 'Ж'
if string(r) == "Ж" {
fmt.Println("совпало")
}
Разбор:
rхранит одну кодовую точку Unicode, а не строку, поэтому прямое сравнениеr == "Ж"было бы ошибкой типов.- Преобразование
string(r)создаёт строку из одного символа и делает сравнение с"Ж"корректным. - Условие в
ifвозвращаетbool, и при совпадении выполняется печать в консоль. - Это типичный реальный паттерн при обработке текста, когда в коде смешиваются
runeиstring.
Связанные материалы
- Справочник по Go — типы, пакеты, concurrency.
- Основы Go — вводный обзор языка.
- История и философия Go — контекст появления языка.