[英]Kotlin: constructor reference for a parameterized type gives a compilation error
我試圖用Kotlin編寫類似於以下Java代碼的內容:
interface Provider {
}
class ProviderImpl1 implements Provider {
}
class ProviderImpl2 implements Provider {
}
enum Providers {
ONE(ProviderImpl1::new),
TWO(ProviderImpl2::new);
private final Supplier<Provider> supplier;
Providers(Supplier<Provider> supplier) {
this.supplier = supplier;
}
public Provider provider() {
return supplier.get();
}
}
此代碼編譯和正常工作: Providers.ONE
產生的一個實例ProviderImpl1
和Providers.TWO
給出的實例ProviderImpl2
。
這是我在Kotlin可以實現的目標:
interface Provider {
}
class ProviderImpl1 : Provider {
}
class ProviderImpl2: Provider {
}
enum class Providers(private val factory: Supplier<Provider>) {
ONE(Supplier{ ProviderImpl1() }),
TWO(Supplier{ ProviderImpl2() });
fun provider(): Provider = factory.get()
}
它可以工作,但是在Java中,我可以在枚舉構造函數中使用構造函數引用。 當我嘗試在科特林做同樣的事情時
ONE( ::ProviderImpl1 ),
我收到以下編譯錯誤:
類型不匹配:推斷的類型為KFunction0,但應為供應商
沒有顯式類型的lambda也不起作用:
ONE( ::ProviderImpl1 )
給
類型不匹配:推斷的類型為()-> ProviderImpl1,但是期望供應商
問題是:Kotlin規范是否禁止這種情況(如果是,是為什么,正如Java似乎要解決的那樣),或者這僅僅是當前Kotlin編譯器的暫時缺陷?
我的build.gradle
具有以下內容
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.2.61'
}
Idea在項目設置中將Kotlin語言版本顯示為1.2。
如果將Supplier
更改為lambda,則可以在Kotlin中很好地實現...
interface Provider
class ProviderImpl1 : Provider
class ProviderImpl2 : Provider
enum class Providers(private val supplier: () -> Provider) {
ONE({ ProviderImpl1() }),
TWO({ ProviderImpl2() });
fun provider(): Provider = supplier.invoke()
}
此處的更改是傳遞返回Provider
實例的函數(本質上是Suppiler
功能)。 很好,因為如果將來您的Provider
實現在構造時需要某種配置,則此lambda可以處理該配置。
如果您的提供程序是無狀態的,則可以通過將Providers.provider()
更改為val
,在該方法中,每個枚舉類型僅創建一次。
您可以像編譯錯誤建議那樣使用kotlin.reflect.KFunction0
而不是java.util.function.Supplier
,然后可以使用方法引用。
例:
import kotlin.reflect.KFunction0
interface Provider {
}
class ProviderImpl1 : Provider {
}
class ProviderImpl2: Provider {
}
enum class Providers(private val factory: KFunction0<Provider>) {
ONE(::ProviderImpl1),
TWO(::ProviderImpl2);
fun provider(): Provider = factory.call()
}
在這種情況下,錯誤消息表明它期望使用java.util.function.Supplier
以外的接口kotlin.reflect.KFunction0
,因此不禁止在此構造方法中使用方法引用。 您可以使用它,只需要使用預期的接口即可。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.