在Kotlin中,我尝试编译以下内容:
以下代码无法编译,因为在以下位置需要类型:
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
函数是inline
,现在具有reified
,泛型类型,这使得该调用在getMapper<Dog>()
上可读性强。
在此处阅读有关reified
的信息:What does the reified keyword in Kotlin really do?
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
函数。真正重要的部分是使这一个通用。未经检查的 Actor 阵容不是很酷,但在这里似乎很安全。