Kotlin:返回一个通用的接口

在Kotlin,我试图编译以下内容:

  1. 给定一个与泛型类型的接口(Printer)
  2. 和该接口的两个实现(DogPrinter和CatPrinter)
  3. 根据外部变量(AnimalType)返回其中一台打印机

下面的代码不能编译,因为需要一个类型: fun getMapper(animalType: AnimalType): Printer

我试图使用<Any><*>但没有成功。 有人可以帮忙吗?

(通过将以下代码复制到https://try.kotlinlang.org,很容易看出错误)

 enum class AnimalType { CAT, DOG } class Dog class Cat interface Printer<in T> { fun mapToString(input: T): String } class DogPrinter : Printer<Dog> { override fun mapToString(input: Dog): String { return "dog" } } class CatPrinter : Printer<Cat> { override fun mapToString(input: Cat): String { return "cat" } } private fun getMapper(animalType: AnimalType): Printer { return when(animalType) { AnimalType.CAT -> CatPrinter() AnimalType.DOG -> DogPrinter() } } fun usage_does_not_compile() { getMapper(AnimalType.DOG) .mapToString(5) } 

我修改了一下你的代码。 getMapper函数现在与reified 泛化类型inline ,这使getMapper<Dog>()的调用非常可读。

阅读关于这里的具体 reified : Kotlin中的关键字关键字是什么?

 private inline fun <reified T> getMapper(): Printer<T> { when (T::class) { Cat::class -> return CatPrinter() as Printer<T> Dog::class -> return DogPrinter() as Printer<T> } throw IllegalArgumentException() } fun main(args: Array<String>) { println(getMapper<Dog>().mapToString(Dog())) println(getMapper<Cat>().mapToString(Cat())) } 

事实上甚至没有必要,但是使得客户端更具可读性。 或者,您也可以将该类作为参数传递给getMapper函数。 真正重要的是使这个通用 。 不加限制的演员阵容不是很酷,但在这里似乎很安全。

Kotlin没有原始类型,所以你不能从getMapper返回Printer 。 您可以返回Printer<*> ,使getMapper通用,或者将您的继承结构更改为具有公共超类型。

返回Printer<*>正常工作。 但它不是实际有用的,因为你不能调用mapToString(Dog()) (我认为mapToString(5)是一个错字),这是一件好事:如果它编译

 getMapper(AnimalType.CAT).mapToString(Dog()) 

也将不得不编译,因为返回类型只能取决于参数类型 ,而不是 ,而AnimalType.CATAnimalType.DOG具有相同的类型。 有一些语言允许它,但Kotlin不是其中之一。