使用默认值推断类types的参数

我有一个这样的构造函数类声明

class Facade( val kClass: KClass = SuperClass::class ) 

这样做是为了让开发人员不必指定SuperClass,如果他们想使用它而不是一个子类。 甚至发送类types的原因是,所以开发人员不必在尖括号中指定types。

但现在出现这个问题。 像下面这样创建实例,表示没有足够的信息来推断参数T.这导致必须将类放在尖括号中。

 Facade() 

但是由于默认值是SuperClass,所以kotlin应该能够将参数T推断为SuperClass。 我在想什么错

谢谢

TL; DR:

 Facade(SubClass:class) // working Facade(SuperClass:class) // working, but don't want (superclass is default) Facade() // working, but don't want angle brackets  Facade() // not working, cannot infer T type from default, why? 

对于Facade()等价于Facade(DerivedClass::class) ,默认的构造函数参数必须声明为val kClass: KClass = T::class 。 但是要使用T::classT型参数需要被实现。 types参数只能在内联函数中指定,而不能在构造函数中指定。

要解决这个问题,你可以声明一个委托给构造函数的工厂函数,如下所示:

 inline fun  Facade(): Facade = Facade(T::class) 

这允许使用它作为例如:

 val derivedFacade:Facade = Facade() 

请注意,如果您想使用SuperClass作为T的默认参数,则需要使用不同的名称声明另一个工厂方法,例如:

 fun SuperFacade(): Facade = Facade() 

这是必需的,因为如果我们声明了@JvmName("SuperFacade") fun Facade() = Facade(SuperClass::class) ,那么只要我们不提供types参数,编译就会匹配它。 这反过来会derivedFacade示例中的types推断。

您可以通过删除尖括号并更改构造器types来解决您的问题。 只需使用这个构造函数:

 class Facade(val kClass: KClass<*> = SuperClass::class) 

所有这些电话正在工作

 Facade(SubClass:class) Facade(SuperClass:class) Facade()