En kotlin, cómo devolver una instancia definida por un parámetro de class genérico

Estoy tratando de escribir un buen envoltorio de Kotlin para un framework web contra kotlin 1.0.3. En eso bash mezclar una function con la request para que devuelva un bean a través de una transformación JSON usando jackson.

Entonces en mi biblioteca tengo lo siguiente

private val mapper: ObjectMapper = ObjectMapper().registerModule(KotlinModule()) fun <T : Any> Request.asDataBean(type: KClass<T>): T = mapper.readValue(this.body(), type.java) 

Pero cuando voy a usar el código como tal

 post("/hello", { req, res -> val bean = req.asDataBean(TestBean::class) }) 

Errores que dicen que el valor esperado de bean es Any. Lo que quiero es que mi API funcione como se indica arriba, donde sea cual sea la definición de "class" genérica que se pasa al método asDataBean es el tipo de valor que se devuelve.

También intenté

 fun <T> Request.asDataBean(type: KClass<*>): T = mapper.readValue(this.body(), type.java) as T 

así como cambiar el código de uso para

 val bean: TestBean = req.asDataBean(TestBean::class) 

con la esperanza de hacerlo funcionar pero también dan el mismo error cuando se usa el código.

¿Cómo hago para usar el genérico definido por el tipo de class pasado como parámetro (muy similar a cómo funcionan todas las API de spring en Java)?

post function de post en su ejemplo requiere una route: (Request, Response) -> Any parámetro, que es una function, que toma la request y la respuesta y devuelve algún valor no nulo.

Cuando utiliza una expresión lambda como route , su tipo de retorno se deduce de la última expresión del cuerpo de lambda, y como en Kotlin una asignación no es una expresión, la siguiente lambda no tiene el tipo de retorno en absoluto:

 { req, res -> val bean = req.asDataBean(TestBean::class) } 

Para que funcione, haz de bean la última expresión

 { req, res -> val bean = req.asDataBean(TestBean::class) bean } 

o no use la asignación en absoluto:

 { req, res -> req.asDataBean(TestBean::class) } 

Nota: He utilizado la siguiente definición de function asDataBean :

 fun <T: Any> Request.asDataBean(type: KClass<T>): T = mapper.readValue(this.body(), type.java) 

También podría hacer una sobrecarga reificada, que llama a una no reificada, para que no tenga que exponer todas las partes internas:

 inline fun <reified T: Any> Request.asDataBean(): T = asDataBean(T::class) req.asDataBean<TestBean>() // usage 

La forma más idiomática de Kotlin sería usar parameters de types reificados :

 inline fun <reified T : Any> Request.asDataBean(): T = mapper.readValue(this.body(), T::class.java) 

Que luego puede ser consumido como:

 post("/hello", { req, res -> val bean = req.bodyAs<TestBean>() res.body("Ok") }) 
  • ¿Puedo enviar la function de extensión a través del parámetro de function?
  • Cómo crear variables en el context principal
  • Modificar "esto" en la function de extensión
  • Kotlin: Cómo extender la class enum con una function de extensión
  • Función de queue Kotlin List
  • Kotlin class NoClassDefFoundError crash
  • Complemento de estudio Android con id: 'kotlin-android-extensions'
  • Cómo corregir la firma del método de extensión genérico en kotlin para resolver "Falló la inferencia de tipo" en kotlin
  • lanza Exception en un método con Kotlin
  • No se puede resolver la cadena suministrada al parámetro vararg en la function de extensión
  • Kotlin: ¿Cómo ejecutar methods de service en el context de una class de transacción?