Так что я просто промокаю ногами от Go и пытаюсь аккуратно обрабатывать ошибки в Go-way.Одним из результатов этого является наличие type Movie struct
с методами для обновления записи и синхронизации с хранилищем данных.Итак, пример метода:
func (movie Movie) SetTitle(title string) : error {
prevTitle := movie.Title
movie.Title = title
json, err := json.Marshal(movie)
if (err != nil) {
movie.Title = prevTitle
return err
}
err = db.SetValue(movie.id, json)
if (err != nil) {
movie.Title = prevTitle
return err
}
return nil
}
Проблема, описанная выше, заключается в том, что «очистка» для сбойной операции заключается в сохранении предыдущего состояния и восстановлении в случае необходимости.Но это кажется очень неосуществимым - так легко сделать новую проверку ошибок в будущем, только чтобы вернуться без надлежащей очистки.Это было бы еще хуже с несколькими такими «чистками».
Для сравнения, в других языках я бы обернул весь бит в try / catch и выполнял очистку только внутри одного блока catch.Здесь я могу:
- Создать копию
movie
, выполнить всю работу с копией, а затем копировать обратно в исходный объект только после того, как все будет успешно - Изменитьлогика:
if json, err := json.Marshal(movie); err == nil {
if err = db.SetValue(...); err == nil {
return nil
}
}
movie.Title = prevTitle;
return err
Что работает, но я не люблю иметь уровень вложенности на проверку.
Измените возвращаемую ошибку, чтобы указать, что она была обновлена локально, но не сохранена Сделайте это, как описано выше Разбейте логику сохранения на функцию
func Update() : err
, чтобы минимизировать количествонужны проверки (просто подумал об этом - думаю, мне нравится этот)
Я чувствую, что ничего из этого не идеально;я что-то упускаю очевидное?