是否可以省略Kotlin中的类型参数



我正在将一台非常旧的大型Java服务器翻译成Kotlin,并试图在转换过程中尽可能少地更改逻辑。我正在寻找一种方法来翻译这段Java代码,而不从根本上改变它

考虑以下玩具代码:

interface Pet
class Dog : Pet
class Cat : Pet
class PetSitter<T : Pet> {
fun walk(pet: T) {}
}
fun main() {
val sitters: Array<PetSitter<*>> =
arrayOf(PetSitter<Cat>(), PetSitter<Dog>())
sitters[0].walk(Cat()) // Type mismatch.
// Required: Nothing
// Found: Cat
}

这无法通过消息Type mismatch: inferred type is Cat but Nothing was expected进行编译。

在Java中,以下操作很好:

PetSitter[] sitters = ... // Note: PetSitter's generic is omitted
sitters[0].walk(new Cat());

有可能在Kotlin中类似地定义Array<PetSitter>(没有宠物通用(吗?或者以其他方式使PetSitter<*>.walk的参数类型为Pet而不是Nothing

在Java中,这被称为原始类型。只有向后兼容性的必要性才支持它,并且不鼓励使用它,因为它违背了使用泛型的目的。出于同样的原因,Kotlin完全禁止它,因为它没有它必须支持的语言的预泛型版本。

使用原始类型的等效方法是将类型强制转换为允许类型。这个要求是为了迫使你考虑演员阵容是否合适。

(sitters[0] as PetSitter<Cat>).walk(Cat())

更新:请参阅https://stackoverflow.com/a/70114733/2875073这更简单。

Kotlin似乎不允许原始类型,但似乎有一个解决方案是将我的Pet实例强制转换为Pet,然后生成一个when事例,枚举每个子类型,并为每个事例强制转换sitters[0]

val myPet: Pet = Cat()
when (myPet) {
is Dog -> (sitters[0] as PetSitter<Dog>).walk(myPet)
is Cat -> (sitters[0] as PetSitter<Cat>).walk(myPet)
}

最新更新