В цепочке Result нужно преобразовать только успешное значение, сохранив исходную ошибку при failure: какой метод выбрать?
Используйте map. Он применяет преобразование только к значению success, а вариант failure передаёт дальше без изменения.
В результате тип успешного значения может измениться, но тип и содержимое ошибки сохраняются.
throws передаёт ошибку через поток выполнения, тогда как Result представляет успех или ошибку как обычное значение. Для работы с таким значением без ручного switch стандартная библиотека предоставляет методы преобразования, включая map, flatMap и mapError.
map решает частую задачу: изменить успешный результат, не затрагивая уже полученную ошибку и не дублируя обработку failure в каждом шаге цепочки.
Предположим, операция вернула Result<Data, NetworkError>, а следующий шаг должен преобразовать Data в модель. При ручной проверке вариантов легко повторить один и тот же код обработки ошибки в нескольких местах.
Неверный выбор метода может привести к вложенным Result, потере исходной ошибки или попытке преобразовать ошибку вместо успешного значения. Поэтому важно различать направление преобразования: map работает с успехом, а mapError — с ошибкой.
map вызывает переданное замыкание только для случая success. Если исходный результат — failure, замыкание не выполняется, а та же ошибка возвращается в новом Result.
В первом случае converted содержит success(8). Во втором случае preserved остаётся failure(.offline); преобразование числа не вызывается.
Сигнатурно map преобразует Result<Success, Failure> в Result<NewSuccess, Failure>. Тип ошибки остаётся тем же, поэтому метод подходит, когда доменная ошибка уже сформирована и её не требуется адаптировать.
Если следующая операция сама возвращает Result, нужен flatMap, иначе получится вложенный тип вроде Result<Result<T, E>, E>. Если необходимо изменить именно ошибку, применяется mapError. map не перехватывает ошибки и не превращает бросающее замыкание в Result.
Главный компромисс — компактность против скрытой последовательности преобразований. Длинная цепочка map удобна для линейных чистых преобразований, но при сложной бизнес-логике явный switch может быть понятнее.
Сервис загрузки возвращает Result<DTO, APIError>, а слой представления использует ViewData. Возможны три подхода: разобрать Result через switch, что максимально явно, но приводит к повторению обработки ошибки; использовать mapError, что неверно, если преобразуется DTO; или применить map, сохранив APIError.
Выбран map, потому что меняется только успешное значение, а ошибка должна без изменений дойти до общего обработчика. В итоге преобразование данных не смешивается с политикой обработки сбоев, а исходная причина ошибки сохраняется для аналитики и отображения.
map, если результат равен failure?Нет. map проверяет вариант Result: для success вызывает замыкание, для failure сразу возвращает ошибочный результат. Поэтому замыкание не должно содержать обязательную очистку или побочные эффекты, которые должны выполняться независимо от результата.
map отличается от flatMap при преобразовании результата?map используется, когда замыкание возвращает обычное значение: T превращается в U. flatMap нужен, когда замыкание возвращает Result<U, E>; он объединяет уровни и предотвращает вложенный Result.
map заменить одну ошибку на другую?Нет. map преобразует только успешное значение. Для преобразования ошибки используется mapError, который сохраняет success без изменений и меняет тип или значение failure. Это позволяет отдельно строить цепочку преобразования данных и адаптации ошибок между слоями приложения.