Generics 泛型密封类的类型安全使用
当我编写泛型密封类时,我发现了一件有趣的事情。以下是第一版:Generics 泛型密封类的类型安全使用,generics,kotlin,covariance,undocumented-behavior,sealed-class,Generics,Kotlin,Covariance,Undocumented Behavior,Sealed Class,当我编写泛型密封类时,我发现了一件有趣的事情。以下是第一版: // sample interface and implementation interface MyInterface class MyInterfaceImpl : MyInterface sealed class Response<T: MyInterface> data class Success<T: MyInterface>(val payload: T) : Re
// sample interface and implementation
interface MyInterface
class MyInterfaceImpl : MyInterface
sealed class Response<T: MyInterface>
data class Success<T: MyInterface>(val payload: T) : Response<T>()
data class Failure(val errorCode: Int) : Response<MyInterface>()
object Cancelled : Response<MyInterface>()
这个宣言很有魅力,现在我有问题:
第二个问题:为什么需要在此处写出修饰符
第三个问题:为什么生产者
是生产者
的子类型?根据协变的定义:Producer
是Producer
的子类型,如果A
是B
的子类型,但是Nothing
不是MyInterface
的子类型。它看起来像是未记录的语言外特征
这种差异最终无法解决<代码>响应
不是响应
,因此不能使用故障
和取消
。即使您没有使用gerneric类型,您仍然要声明它
当把放在T
外时,你会产生类似的效果?在Java中扩展T
那么对于你来说:
凡事皆有实例。你不能用任何东西来表示“一个永远不存在的价值”
这也意味着它是所有事物的子类型,因此也适用于泛型。“但没有任何东西不是MyInterface的子类型”-是的,它是<代码>无是每种类型的子类型。(这是可能的,因为它没有值。)感谢您的回复,但我不能完全同意您的意见,因为我已经尝试用Java扩展
响应
,我有?扩展T
,包括和不包括“out projection”这也意味着它是所有事物的子类型,因此也适用于泛型“您将其作为引用发布,但我认为这只是您的猜测。我在文档和《Kotlin in in action》一书中都找不到这样的定义,这是一个结论。如果没有实例,则始终可以在没有差异的情况下使用它。这就是TODO()
的工作原理。报价部分是一个格式问题。另一方面,Kotlin可与Java相媲美,但与Java不同。我无法猜测两者之间的相互作用。
fun <T: MyInterface> requestObject(cls : KClass<T>): Response<T> = TODO("Request")
fun test() = when (val response = requestObject(MyInterfaceImpl::class)) {
is Success -> print("Payload is ${response.payload}") // Smart cast perfectly works!
is Failure -> print("Error code ${response.errorCode}") // Incomparable types: Failure and Response<MyInterfaceImpl>
Cancelled -> print("Request cancelled") // Incomparable types: Cancelled and Response<MyInterfaceImpl>
}
sealed class Response<out T: MyInterface> // <-- out modifier here
data class Success<T: MyInterface>(val payload: T) : Response<T>()
data class Failure(val errorCode: Int) : Response<Nothing>() // <-- Nothing as type argument
object Cancelled : Response<Nothing>() // <-- Nothing as type argument