Kotlin - Как правильно отобразить результат, используя Either? - PullRequest
0 голосов
/ 01 марта 2019

Я пытаюсь прочитать список объектов из базы данных и сопоставить его с другим типом списка.

// Returns either a Failure or the expected result
suspend fun getCountries(): Either<Failure, List<CountryItem>> {
    // Get the result from the database
    val result = countryLocalDataSource.getCountries()

    // Left means Failure
    if (result.isLeft) {
        // Retrieve the error from the database
        lateinit var error: Failure
        result.either({
            error = it
        }, {})

        // Return the result
        return Either.Left(error)
    }

    // The database returns a List of Country objects, we need to map it to another object (CountryItem)
    val countryItems: MutableList<CountryItem> = mutableListOf()

    // Iterate the Country List and construct a new List of CountryItems
    result.map { countries -> {
        countries.forEach {
            // Assign some values from an Enum (localized string resources)
            val countryEnumValue = Countries.fromId(it.id)
            countryEnumValue?.let { countryIt ->
                val countryStringNameRes = countryIt.nameStringRes;

                // Create the new CountryItem object (@StringRes value: Int, isSelected: Bool)
                countryItems.add(CountryItem(countryStringNameRes, false))
            }
        }
    } }

    // Because this is a success, return as Right with the newly created List of CountryItems
    return Either.Right(countryItems)
}

Ради удобства чтения я не включил весь Repository илиDAO классов и я оставил комментарии в фрагменте кода выше.

В двух словах : я использую Coroutines Kotlin для доступа к базе данных вразделенный поток, и я обрабатываю ответ на UI Thread.Использование класса Either для возврата двух разных результатов (неудача или успех).

Приведенный выше код работает, однако он слишком уродлив.Это правильный подход для получения результата?

Я пытаюсь реорганизовать приведенный выше код.

Вся проблема вызвана двумя разными типами объектов,Database Data Source API возвращает Either<Failure, List<Country>>, в то время как ожидается, что функция вернет Either<Failure, List<CountryItem>>.

Я не могу доставить List<CountryItem> напрямую из Database Data Source API, потому что Android Studio не 'Позвольте мне скомпилировать проект (объекты, реализующие интерфейсы, ошибки компиляции и т. д.).То, чего я пытаюсь добиться, - это отобразить результат Either более хорошим способом.

Ответы [ 2 ]

0 голосов
/ 02 марта 2019

Вы можете упростить проверку типа Either и непосредственный доступ к значению.В вашем случае:

доступ Left через result.a -> Failure

доступ Right через result.b -> List<Country>

например:

when (result) {
    is Either.Left -> {
        val failure: Failure = result.b
        ...
    }
    is Either.Right -> {
        val countries: List<Country> = result.b
        ...
    }
}

Альтернативой является использование функции either() (обычно это называется fold()):

result.either(
    { /** called when Left; it == Failure */ }, 
    { /** called when Right; it == List<Country> */ }
)
0 голосов
/ 01 марта 2019

Попробуйте использовать Результат Котлина

Так что в вашем случае вы можете написать что-то вроде:

return result.mapCatching { list: List<Country> -> /*return here List<CountryItem>>*/ }

И для проверки результата вызова:

result.fold(
    onSuccess = {...},
    onFailure = {...}
)

Чтобы вызвать конструктор, вы должны вызвать Result.success(T) или Result.failure(Throwable)

К сожалению, вам также необходимо подавить предупреждения типа использования как возвращаемые Как

...