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