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
Упражнение не проходит проверку — что делать? 😶
Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:
- Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.
В моей среде код работает, а здесь нет 🤨
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Мой код отличается от решения учителя 🤔
Это нормально 🙆, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.
В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Прочитал урок — ничего не понятно 🙄
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.
Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.