Перейти до основного вмісту
Модуль 3 · Урок 2 із 512/50 у курсі~12 min
Модульні уроки (2/5)

Множинні повернення та іменовані повернення

У Go функція може повертати кілька значень. Це механізм, який вмикає шаблон (value, error), який ви вже бачили, і який пронизує всю стандартну бібліотеку.

Кілька повернень

Типи повернення вказуються в круглих дужках, розділених комами:

Go
func divmod(a, b int) (int, int) {
    return a / b, a % b
}

q, r := divmod(17, 5) // q=3, r=2

Вони деструктуровані з множинним призначенням. Відкинути один із значення використовують _:

Go
_, r := divmod(17, 5) // solo il resto

Канонічний шаблон (T, error)

Майже весь stdlib слідує за ним. error ЗАВЖДИ останній:

Go
func read(path string) ([]byte, error) {
    data, err := os.ReadFile(path)
    if err != nil {
        return nil, fmt.Errorf("read %q: %w", path, err)
    }
    return data, nil
}

Іменовані повернення

Ви можете називати значення, що повертаються: вони стають попередньо оголошеними змінними ініціалізується нулем, а return без аргументів повертає їх ("голі повернення"):

Go
func divmod(a, b int) (q, r int) {
    q = a / b
    r = a % b
    return       // naked: ritorna q, r
}

Іменовані повернення також відображаються в підказках документації, тому вони корисні як форму вбудованої документації для складних функцій — а не просто для голого повернення.

Більше двох повернень?

Ніщо не заважає вам (int, int, int, error), але якщо ви відчуваєте потребу це майже завжди означає, що ви повинні повернути struct:

Go
type Result struct {
    Sum  int
    Avg  float64
    Max  int
}

func analyze(nums []int) (Result, error) { ... }

Спробуйте

вправи#go.m3.l2.e1
Спроби: 0Завантаження…

Визначте divmod(a, b int) (int, int), який повертає частку та залишок.

Завантаження редактора…
Показати підказку

Типи результатів між дужками: `(int, int)`.

Рішення доступне після 3 спроб

вправи#go.m3.l2.e2
Спроби: 0Завантаження…

Реалізація safeDiv(a, b int) (int, error): if b == 0 повертає (0, errors.New('divisione per zero')), інакше (a/b, nil).

Завантаження редактора…
Показати підказку

Помилка ЗАВЖДИ як останнє значення. При помилці: нульове значення + помилка.

Рішення доступне після 3 спроб

Quiz#go.m3.l2.e3
Готовий

Що ця програма друкує, використовуючи іменовані повернення?

Go
func f() (a, b int) {
    a = 1
    b = 2
    return
}
x, y := f()
fmt.Println(x, y)
Варіанти відповідей

Підведення підсумків

  • Кілька значень у круглих дужках: func f() (T1, T2, error).
  • Конвенція: error ЗАВЖДИ як останнє значення; на помилку, нульове значення + помилка.
  • Іменовані повернення попередньо оголошують змінні та дозволяють оголені повернення.
  • Оголені повернення лише в дуже коротких функціях; крім того, страждає читабельність.
  • Більше 2-3 повернень? Можливо, вам потрібна структура.