0

我在我的服务中创建了一个自定义结果字段(而不是 Kotlin 的结果),因此我可以在成功和失败案例中返回一个消息字段:

sealed class Result<T> {
    data class Success<T>(val value: T, val message: String) : Result<T>()

    data class Failure<T>(val throwable: Throwable? = null, val message: String) : Result<T>() {
        val isExceptional = throwable != null
        val error: Throwable
            get() = throwable ?: error("Error is undefined in [$this]")
    }
}

然后在另一个类中,我调用了一个产生此结果的方法并希望记录 Result.message

logger.info { "Finished with message [${result.message}]." }

只是,kotlin 编译器无法识别“消息”,因为它不是 Result 的直接属性,而是 Success 和 Failure 的属性。

我试图覆盖消息字段并在 Result 类中定义它。但我得到一个错误。

Error:(10, 38) Kotlin: 'message' in 'Result' is final and cannot be overridden

那么,如何在不将结果实例强制转换为它的派生实现类(成功或失败)的情况下访问 Result.message 呢?

4

3 回答 3

1

我找到的一个干净的解决方案如下。

而 Kotlin 不允许我们覆盖密封的类成员。它确实允许我们覆盖接口成员。

因此,我为消息字段创建了一个简单的接口,并从 Result 类中实现了它:

interface ResultMessage {
    val message: String
}

sealed class Result<T> : ResultMessage

// Now I'm able to override the message field simply, with no error
data class Success<T>(val value: T, override val message: String) : Result<T>()

data class Failure<T>(val throwable: Throwable? = null, override val message: String) : Result<T>() {
    val isExceptional = throwable != null
    val error: Throwable
        get() = throwable ?: error("Error is undefined in [$this]")
}
于 2021-02-28T16:48:52.787 回答
1

1-您可以将它们标记为打开

open val message: String = ""

2-您可以将它们定义为抽象的

abstract val message: String
于 2021-02-28T16:19:50.250 回答
1

您可以在类中声明一个抽象属性Result

sealed class Result<T> {
    abstract val message: String
    data class Success<T>(val value: T, override val message: String) : Result<T>()

    data class Failure<T>(val throwable: Throwable? = null, override val message: String) : Result<T>() {
        val isExceptional = throwable != null
        val error: Throwable
            get() = throwable ?: error("Error is undefined in [$this]")
    }
}

不过,您的解决方案也是一种选择

于 2021-02-28T17:26:59.823 回答