你如何编写types参数的类的二级构造函数?

假设我有下面的类,并带有一个types参数T(在这个例子中它是有界的,以帮助说明后面的例子,但是当它是无界的时候,错误仍然存​​在):

class GenericsTest(private var cs: T) 

现在假设我想为这个类添加一个辅助构造函数。 我怎样才能做到这一点? 我第一次(天真)的尝试导致了一个编译器错误:

 class GenericsTest(private var cs: T) { // dummy exists to ensure the method signatures are different constructor(cs: String, dummy: Int) : this("a") } 

IntelliJ强调"a"与消息:

 Type mismatch. Required: T Found: String 

对我来说, String似乎是一个完全有效的T 我想明确指定types参数会有所帮助,但似乎不被允许。 这两种尝试都是不正确的语法:

 constructor(cs: String, dummy: Int) : this("a") constructor(cs: U, dummy: Int) : this("a") 

由于我怀疑所有这些场景都有一个共同的方法,我的主要问题是:

你如何在Kotlin中为generics类编写二级构造函数? 或者类似地,当构造函数具有types参数时,如何委托给主构造函数?

这甚至有可能吗? 如果没有,一个解决方法可能是使用辅助函数来使用主构造函数来创建对象,但这不适用于例如抽象类。

generics的官方文档不讨论构造函数。

将辅助函数分组的另一种方法是:辅助对象可以被调用。

 class GenericsTest(private var cs: T) { companion object { operator fun invoke(cs: String, dummy: Int) = GenericsTest(cs) } } GenericsTest("a", 1) 

这不是一个真正的构造函数,但它看起来像一个。 独立函数的一个好处是,即使被调用的构造函数是private ,它也可以工作。

根据文件 :

如果类具有主构造函数,则每个次构造函数都需要通过另一个辅助构造函数直接或间接地委托给主构造函数。

GenericsTest签名主构造函数声明它接受任何实现CharSequencetypes。 由于二级构造函数类必须调用主构造函数,所以它也必须支持任何实现CharSequencetypes。 无论我们选择哪个构造函数来实例化GenericsTest我们应该可以为任何 T: CharSequence而不仅仅是String ,因此编译器会抱怨Type mismatch

你已经提到了一个涉及辅助函数的工作,例如:

 fun GenericsTest(cs: String) = GenericsTest(cs) fun GenericsTest(cs: CharBuffer, other:Int) = GenericsTest(cs) 

正如你所提到的,辅助函数不适用于抽象类。 然而,抽象类允许派生types专业化,例如:

 class StringsTest(s: T) : GenericsTest(s) 

对于抽象基类来说,几乎不可能或不可能(从设计的角度来看,开放的封闭原则)声明一些东西,这些东西只能从genericstypes的派生类直接获得。