Kotlin:泛型方法参数的默认值



为什么这个是正确的,下面这个是错误的?

正确

fun main () {
AppModule().provideHttpClient(CIO)
}

错误
fun <T : HttpClientEngineConfig> provideHttpClient(engineFactory: HttpClientEngineFactory<T> = CIO): HttpClient

类型不匹配。
Required:HttpClientEngineFactory
Found: CIO

CIO被定义为:

public object CIO : HttpClientEngineFactory<CIOEngineConfig> {
init {
addToLoader()
}
override fun create(block: CIOEngineConfig.() -> Unit): HttpClientEngine =
CIOEngine(CIOEngineConfig().apply(block))
override fun toString(): String = "CIO"
}

泛型方法的语义是"我使用任何类型",因此泛型方法的类型参数由调用者指定——调用者决定T是什么。因此,对于调用者可能传入的任何T,您指定作为被调用者的默认值必须与HttpClientEngineFactory<T>兼容。

使用CIO在这里不起作用,因为您正在强制TCIOEngineConfig

想象一下,如果允许默认值CIO,并且调用者这样做会发生什么:

AppModule().provideHttpClient<SomeOtherEngineConfig>()

从声明provideHttpClient的方式来看,这应该是可能的-我为泛型类型参数T传递SomeOtherEngineConfig,并且由于engineFactory参数具有默认值,因此我不需要传递任何其他参数。但是当它实际运行时,默认值CIO用于类型为HttpClientEngineFactory<SomeOtherEngineConfig>的参数!

很容易解决这个问题:只需声明另一个非泛型的provideHttpClient重载:

fun provideHttpClient(): HttpClient = provideHttpClient(CIO)

最新更新