简体   繁体   English

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

[英]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必需:HttpClientEngineFactory
Found: CIO发现:首席信息官

With CIO being defined as: CIO被定义为:

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

Using CIO doesn't work here, because you are forcing T to be CIOEngineConfig .在这里使用CIO不起作用,因为您强制T成为CIOEngineConfig

Imagine what would happen if the default value of CIO was allowed, and the caller did:想象一下,如果允许CIO的默认值,并且调用者这样做了,会发生什么:

 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.从声明provideHttpClient的方式来看,这应该是可能的 - 我为泛型类型参数T传递SomeOtherEngineConfig ,并且由于engineFactory参数具有默认值,因此我不需要传递任何其他参数。 But when this actually gets run, the default value of CIO is used for a parameter of type HttpClientEngineFactory<SomeOtherEngineConfig> !但是当它实际运行时, CIO的默认值用于HttpClientEngineFactory<SomeOtherEngineConfig>类型的参数!

It's easy to workaround this: simply declare another overload of provideHttpClient that is not generic:解决这个问题很容易:只需声明另一个非通用的provideHttpClient重载:

 fun provideHttpClient(): HttpClient = provideHttpClient(CIO)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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