Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

183
Vistas
Devolver un objeto anónimo de la función e inferir el tipo en Kotlin

Vengo de Java y soy nuevo en Kotlin. Estoy tratando de crear DSL declarativo para fines de prueba unitaria. Aquí está mi intento de crear un método de construcción genérico para construir cualquier objeto modelo con sintaxis declarativa.

 fun <T> having(t: Class<T>) = object { infix fun with(fn: T.() -> Unit) = t.newInstance().apply(fn) } fun test() { having(Pizza::class.java) with { size = Size.NORMAL cheese = Cheese.MOZARELLA } }

Sin embargo, la función de having devuelve Any tipo con referencia no resuelta a with función. Podría extraer el objeto anónimo a su propia clase para compilarlo, pero se sentiría redundante. ¿Es posible recurrir a la inferencia de tipo con funciones que devuelven instancias de un object ?

Además, no estoy seguro de si estoy usando genéricos de forma idiomática aquí.

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

El motivo por el cual el tipo de retorno de la función de having se infiere como Any se explica en mi respuesta aquí . Básicamente, tendrá que hacer que having private para que infiera el tipo de retorno deseado. Obviamente, esa no es una solución viable para su unidad de prueba DSL, que será utilizada por el código en otros archivos.

Puede considerar eliminar la palabra having y declarar directamente with como una función de extensión/infijo en KClass .

Función de extensión:

 fun <T: Any> KClass<T>.with(fn: T.() -> Unit) = this.createInstance().apply(fn) // ... Pizza::class.with { size = Size.NORMAL cheese = Cheese.MOZZARELLA }

Función de infijo:

 infix fun <T: Any> KClass<T>.with(fn: T.() -> Unit) = this.createInstance().apply(fn) fun main() { Pizza::class with { size = Size.NORMAL cheese = Cheese.MOZZARELLA } }
over 4 years ago · Santiago Trujillo Denunciar

0

En lugar de devolver un object de tipo no especificado, puede devolver un objeto envolvente, que declara la función with y contiene el objeto de clase original.

De esta manera, obtiene seguridad de tipo, al mismo tiempo having conserva su DSL de estilo.

 data class WrappedInstance<T>(val data: T) { infix fun with(applyFn: T.() -> Unit): T = data.also(applyFn) } fun <T : Any> having(kClass: KClass<T>): WrappedInstance<T> = WrappedInstance(kClass.createInstance())

Usándolo, se ve así:

 data class Pizza(var size: Int = 1, var cheese: Int = 1) fun test() { val pizza: Pizza = having(Pizza::class) with { size = 3 cheese = 5 } println(pizza.size) println(pizza.cheese) }

Sin embargo, tenga en cuenta que tanto este como su enfoque original tienen una advertencia. Solo funcionan para clases con constructores, que no requieren ningún parámetro.

Consulte la documentación de KClass<T>.createInstance() :

Crea una nueva instancia de la clase, llamando a un constructor que no tiene parámetros o todos los parámetros son opcionales (consulte KParameter.isOptional). Si no hay o hay muchos constructores de este tipo, se lanza una excepción.


Cuando no sea necesario having parte del DSL, consulte la solución de @Sweeper .

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda