Estoy traduciendo un servidor Java muy antiguo y grande a Kotlin, y estoy tratando de hacer la menor cantidad de cambios lógicos posibles durante la conversión. Estoy buscando una manera de traducir este fragmento de código Java sin cambiarlo fundamentalmente.
Considere el siguiente código de juguete:
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 }
Esto no se puede compilar con el mensaje Error de Type mismatch: inferred type is Cat but Nothing was expected
.
En Java lo siguiente funciona bien:
PetSitter[] sitters = ... // Note: PetSitter's generic is omitted sitters[0].walk(new Cat());
¿Es posible definir de manera similar un Array<PetSitter>
(sin mascota genérica) en Kotlin? ¿O alguna otra forma de hacer que el tipo de parámetro para PetSitter<*>.walk
sea Pet
en lugar de Nothing
?
En Java, esto se denomina tipo sin procesar. Solo se admite por necesidad para la compatibilidad con versiones anteriores, y se desaconseja su uso, ya que anula el propósito de usar genéricos. Por la misma razón, Kotlin lo prohíbe rotundamente porque no tiene una versión pregenérica del lenguaje que debe admitir.
El equivalente de usar un tipo sin procesar es convertir los tipos para que sean permisivos. Este requisito es para obligarte a considerar si el yeso es adecuado.
(sitters[0] as PetSitter<Cat>).walk(Cat())
Actualización: consulte https://stackoverflow.com/a/70114733/2875073 , que es más simple.
Parece que Kotlin no permite tipos sin formato, pero parece que una solución alternativa es emitir mi instancia de Mascota a Pet
y luego hacer un caso when
el que se enumere cada subtipo y se emitan sitters[0]
para cada caso:
val myPet: Pet = Cat() when (myPet) { is Dog -> (sitters[0] as PetSitter<Dog>).walk(myPet) is Cat -> (sitters[0] as PetSitter<Cat>).walk(myPet) }