Использование обобщений для инкапсуляции ответов в Kotlin, таких как swift - PullRequest
1 голос
/ 08 ноября 2019

В Swift перечисление может быть создано с универсальным типом, так что ответ об ошибке может быть передан либо только с успешным случаем, либо с ошибкой. Поэтому я могу объявить:

/// An enum that boxes API results as either success or failure cases.
public enum APIResult<T>
{
    /// The request succeeded with data.
    case success(data: T)

    /// Encapsulates the type of error along with optional user-facing description string and developer-facing debug strings.
    case failure(error: Error, response: ErrorResponse?)
}

, а затем использовать его следующим образом:

fileprivate func myHandler(_ result: APIResult<MyResponse>) {
    switch result {

    // #1 (API Request succeeds)
    case .success(let response):
        switch response.myField {
          // handle success 
        }
    ...
    // #2 (API Request failed)
    case .failure(let error, let response):
}

Просмотрев страницу Общие инструкции в Котлине, неясно,мне, как упаковывать объекты подобным образом, используя Kotlin. Может ли кто-нибудь указать мне правильное направление, чтобы дублировать интерфейс, как это?

Ответы [ 2 ]

0 голосов
/ 11 ноября 2019

Для @AjahnCharles, в итоге я решил использовать класс Result<T>, который работал очень хорошо.

В java у меня может быть:

public class VersionCheckStatus {

    @Expose
    String supported;

    @Expose
    String reason;

    public VersionCheckStatus(String supported, String reason) {
        this.supported = supported;
        this.reason = reason;
    }

    public String getSupported() {
        return supported;
    }

    public void setSupported(String supported) {
        this.supported = supported;
    }

    public String getReason() {
        return reason;
    }

    public void setReason(String reason) {
        this.reason = reason;
    }

    /**
     * Provides enum translation for easily checking the status of the response object
     *
     * @return enum status
     */
    public VersionCheckManager.Status getEnumStatus() {

        if (supported.equals(VersionCheckManager.Status.YES.toString())) {
            return VersionCheckManager.Status.YES;
        } else if (supported.equals(VersionCheckManager.Status.NO.toString())) {
            return VersionCheckManager.Status.NO;
        } 
        return VersionCheckManager.Status.NO;
    }
}

. Затем определите функцию kotlin, например:

override fun establishCompatibility(callback: (Result<VersionCheckStatus>) -> Unit) {
...
}

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

manager.establishCompatibility { versionCheckStatus ->

    var textToShow = ""
    versionCheckStatus.fold({ successResult ->
        textToShow = when (successResult.enumStatus) {
            VersionCheckManager.Status.YES -> "Yes:\n ${successResult.reason}"
            VersionCheckManager.Status.NO -> No:\n ${successResult.reason}"
            null -> "Unknown"
        }
    }, { throwable ->
        textToShow = "Exception occurred:\n $throwable"
    })

    Toast.makeText(this, textToShow, Toast.LENGTH_LONG).show()
}
0 голосов
/ 08 ноября 2019

Как предлагается в комментарии, вы можете использовать запечатанные классы для той же цели.

Если вы не хотите создавать свои собственные классы (и / или вы хотите программировать функциональный стиль), вы можете использовать Arrow'sпредопределенные классы, такие как Either или более конкретные Try. У них также есть некоторые полезные дополнения.

https://arrow -kt.io / docs / arrow / core / try /

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...