Бесплатный курс по go. Зарегистрируйтесь для отслеживания прогресса →

Go: Отложенные функции

В Go есть полезная конструкция defer, которая позволяет выполнять функции в фазе выхода из текущей функции. Например:

package main

import (
    "fmt"
)

func main() {
    // функция выполнится в самом конце при выходе из main
    defer fmt.Println("finish")

    fmt.Println("start")
}

Вывод:

start
finish

Такие функции называются отложенными. Каждая такая функция добавляется в стек отложенных функций и будет выполнена в порядке LIFO (Last In First Out):

package main

import (
    "fmt"
)

func main() {
    defer fmt.Println("3rd")
    defer fmt.Println("2nd")

    fmt.Println("1st")
}

Вывод:

1st
2nd
3rd

Использование отложенных функций достаточно распространено. Например:
- закрытие дескриптора файла после работы
- возвращение соединения с базой данных в общий пул после чтения всех строк
- закрытие TCP соединения после полного прочтения тела ответа

Задание

Реализуйте функцию ExecuteMergeDictsJob(job *MergeDictsJob) (*MergeDictsJob, error), которая выполняет джобу MergeDictsJob и возвращает ее. Алгоритм обработки джобы следующий:
- перебрать по порядку все словари job.Dicts и записать каждое ключ-значение в результирующую мапу job.Merged
- если в структуре job.Dicts меньше 2-х словарей, возвращается ошибка errNotEnoughDicts = errors.New("at least 2 dictionaries are required")
- если в структуре job.Dicts встречается словарь в виде нулевого значения nil, то возвращается ошибка errNilDict = errors.New("nil dictionary")
- независимо от успешного выполнения или ошибки в возвращаемой структуре MergeDictsJob поле IsFinished должно быть заполнено как true

Пример работы:

ExecuteMergeDictsJob(&MergeDictsJob{}) // &MergeDictsJob{IsFinished: true}, "at least 2 dictionaries are required"
ExecuteMergeDictsJob(&MergeDictsJob{Dicts: []map[string]string{{"a": "b"},nil}}) // &MergeDictsJob{IsFinished: true, Dicts: []map[string]string{{"a": "b"},nil}}, "nil dictionary"
ExecuteMergeDictsJob(&MergeDictsJob{Dicts: []map[string]string{{"a": "b"},{"b": "c"}}}) // &MergeDictsJob{IsFinished: true, Dicts: []map[string]string{{"a": "b", "b": "c"}}}, nil

Советы


Нашли ошибку? Есть что добавить? Пулреквесты приветствуются https://github.com/hexlet-basics
Если вы столкнулись с трудностями и не знаете, что делать, задайте вопрос в нашем большом и дружном сообществе