简体   繁体   中英

Kotlin: Default value for the argument(s) of generic method

Why this is correct and the below one is wrong?

Correct one

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

Wrong

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

Type mismatch.
Required:HttpClientEngineFactory
Found: CIO

With CIO being defined as:

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

The semantics of a generic method is that "I work with any type", so the type parameters of a generic method is specified by the caller - the caller gets to decide what T is. Therefore, the default value that you specify as the callee must be compatible with HttpClientEngineFactory<T> , for any T that the caller might pass in.

Using CIO doesn't work here, because you are forcing T to be CIOEngineConfig .

Imagine what would happen if the default value of CIO was allowed, and the caller did:

 AppModule().provideHttpClient<SomeOtherEngineConfig>()

From the way that provideHttpClient is declared, this should be possible - I'm passing SomeOtherEngineConfig for the generic type parameter T , and since the engineFactory parameter has a default value, I don't need to pass any other parameters. But when this actually gets run, the default value of CIO is used for a parameter of type HttpClientEngineFactory<SomeOtherEngineConfig> !

It's easy to workaround this: simply declare another overload of provideHttpClient that is not generic:

 fun provideHttpClient(): HttpClient = provideHttpClient(CIO)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM