Kotlin:返回一个通用接口

Ric*_*ior 6 generics kotlin

在 Kotlin 中,我正在尝试编译以下内容:

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

以下代码无法编译,因为在以下位置需要类型: fun getMapper(animalType: AnimalType): Printer

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

(通过将下面的代码复制粘贴到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)
}
Run Code Online (Sandbox Code Playgroud)

s1m*_*nw1 5

我稍微修改了你的代码。该getMapper函数现在inline具有reified 泛型类型,这使得调用在getMapper<Dog>().

reified这里阅读:Kotlin 中的 reified 关键字到底有什么作用?

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()))
}
Run Code Online (Sandbox Code Playgroud)

具体化的东西实际上甚至不是必需的,而是使客户端更具可读性。或者,您也可以将类作为参数传递给getMapper函数。真正重要的部分是使这个通用。未经检查的演员表不是很酷,但在这里似乎是安全的。