Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 6

Функции с несколькими параметрами и возвращаемыми значениями

Recommended resources

Здравствуйте!

На прошлом уроке мы разобрали, как оператор := может приводить к непреднамеренному затенению переменных. Вы познакомились с идиоматичным паттерном value, err := someFunc(), который часто является источником таких ситуаций. Сегодня мы углубимся в то, что стоит за этим синтаксисом, и подробно изучим функции в Go.

Цель этого урока — научиться писать функции с несколькими параметрами и, что особенно важно, с несколькими возвращаемыми значениями. Эта возможность является одной из ключевых особенностей Go и кардинально отличает его подход к обработке ошибок от привычных вам try...catch или промисов в TypeScript/JavaScript. Понимание этого механизма — фундаментальный шаг к написанию идиоматичного кода на Go.

Определение функции и её параметры

Синтаксис объявления функций в Go прост и лаконичен. Как и во многих языках, он начинается с ключевого слова, за которым следуют имя, параметры и тело функции.

Определение и вызов функций в Go

Прочтите статью от DigitalOcean, чтобы ознакомиться с основами.

В статье изучите разделы "Определение функции" и "Работа с параметрами". Обратите внимание на: Ключевое слово func. Особую роль функции main(). Синтаксис объявления параметров: имя тип. Удобный сокращенный синтаксис для нескольких параметров одного типа: func addNumbers(x, y, z int).

Как вы видите, синтаксис в целом знаком. Главное отличие от TypeScript — тип указывается после имени переменной, что является общей чертой для многих современных языков, включая Go.


Возврат нескольких значений

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

Learn Functions in Go with Examples | golangbot.com

Давайте рассмотрим, как объявлять и использовать функции, возвращающие несколько значений. В этой статье от golangbot.com есть наглядный пример.

Прочтите раздел "Multiple return values". Обратите внимание на то, как типы возвращаемых значений заключаются в скобки (float64, float64), а при вызове функции результаты присваиваются нескольким переменным одновременно: area, perimeter := rectProps(...).

Эта возможность позволяет функции передать "наверх" не только основной результат своей работы, но и дополнительную информацию, например, статус выполнения.


Идиома (value, error)

Самое распространенное применение множественных возвращаемых значений — это обработка ошибок. В Go нет исключений в том виде, в котором они существуют в JavaScript, Java или Python. Вместо этого принято, чтобы функция, которая может завершиться с ошибкой, возвращала два значения: результат и ошибку.

Если операция прошла успешно, возвращается результат и nil в качестве ошибки. Если произошла ошибка, возвращается нулевое значение для типа результата и сама ошибка.

Определение и вызов функций в Go

Вернемся к статье от DigitalOcean, чтобы увидеть этот паттерн в действии.

Изучите раздел "Возврат нескольких значений". Пример с функцией repeat идеально иллюстрирует идиому (string, error). Обратите внимание на проверку if err != nil сразу после вызова функции — это канонический способ обработки ошибок в Go.

Такой подход делает поток управления абсолютно явным. Каждая потенциальная ошибка обрабатывается на месте, а не "всплывает" по стеку вызовов, как в случае с throw. Это требует большей дисциплины от программиста, но делает код более предсказуемым и надежным.


Игнорирование возвращаемых значений

Что делать, если вам не нужно одно из возвращаемых значений? Компилятор Go не позволит вам объявить переменную и не использовать ее. Для таких случаев существует пустой идентификатор (blank identifier) — _.

Learn Functions in Go with Examples | golangbot.com

В статье на golangbot.com хорошо описано применение пустого идентификатора.

Прочтите раздел "Blank Identifier". В примере area, _ := rectProps(...) второе возвращаемое значение (периметр) сознательно отбрасывается.

Вы будете часто встречать _ при вызове функций, которые возвращают ошибку, в ситуациях, когда вы уверены, что ошибка не произойдет, или когда вы сознательно ее игнорируете (хотя последнее следует делать с осторожностью).


Именованные возвращаемые значения

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

На этой схеме показана функция `calculator` с именованными возвращаемыми значениями `mul` и `div`. Обратите внимание, что `return` используется без аргументов.

Эти именованные переменные ведут себя как локальные переменные, объявленные в начале функции. Им можно присваивать значения, а "голый" return в конце функции автоматически вернет их текущие значения.

Learn Functions in Go with Examples | golangbot.com

Давайте посмотрим на текстовое объяснение этого механизма.

Прочтите раздел "Named return values". Этот синтаксис не только сокращает код, но и служит своего рода документацией, явно указывая, что именно функция возвращает.

Использовать именованные возвращаемые значения или нет — вопрос стиля. Они полезны в коротких функциях, где связь между присваиванием и возвратом очевидна. В длинных и сложных функциях они могут, наоборот, запутать, так как return в конце не показывает явно, какие значения возвращаются.


Видимость функций: Экспорт

Наконец, кратко коснемся важного аспекта, связанного с определением функций в Go, — их видимости за пределами пакета. В отличие от JavaScript с его явным ключевым словом export, в Go видимость определяется очень просто: регистром первой буквы имени.

Golang Tutorial for JavaScript Developers

В этом видео автор, объясняя Go для JavaScript-разработчиков, наглядно демонстрирует механизм экспорта.

Посмотрите фрагмент об экспорте кода. Основная идея: если имя функции (или переменной) начинается с заглавной буквы (например, Add), она экспортируется и доступна из других пакетов. Если с маленькой (например, subtract), она является приватной для текущего пакета.

Это простое правило — еще одна фундаментальная концепция Go, которая способствует созданию четких границ между пакетами.


Итоги

В этом уроке мы рассмотрели один из самых важных аспектов языка Go — функции и их способность возвращать несколько значений.

  • Функции объявляются с помощью ключевого слова func. Типы указываются после имен параметров и возвращаемых значений.
  • Функция может возвращать несколько значений, которые объявляются в скобках: func() (string, int).
  • Идиоматический способ обработки ошибок в Go — это возврат пары (value, error). Успех сигнализируется возвратом nil в качестве ошибки.
  • Пустой идентификатор _ используется для игнорирования ненужных возвращаемых значений.
  • Именованные возвращаемые значения позволяют объявить возвращаемые переменные в сигнатуре функции и использовать "голый" return.
  • Видимость функции определяется регистром первой буквы ее имени: заглавная — экспортируется, строчная — приватная для пакета.

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

В следующем уроке мы изучим еще одну мощную концепцию: функции как значения и замыкания. Эта тема будет вам особенно близка благодаря вашему опыту в JavaScript, где функции являются объектами первого класса.