Kotlin:动态类型参数的默认值

Kotlin: Default value for dynamically typed arguments

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

正确一个

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

错误

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

Type mismatch.
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 不起作用,因为您将 T 强制为 CIOEngineConfig

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

AppModule().provideHttpClient<SomeOtherEngineConfig>()

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

类型的参数

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

fun provideHttpClient(): HttpClient = provideHttpClient(CIO)