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") }) 
  • Métodos de interfaz de anulación de Android kotlin dentro del método onCreateView ()
  • ¿A los miembros protegidos no se puede acceder en las funciones de extensión?
  • Android Studio y Kotlin: reference no resuelta: también
  • lanza Exception en un método con Kotlin
  • Kotlin: Cómo extender la class enum con una function de extensión
  • While loop en el lenguaje de progtwigción Kotlin
  • ¿Cómo se pueden agregar methods estáticos a las classs de Java en Kotlin?
  • Cómo corregir la firma del método de extensión genérico en kotlin para resolver "Falló la inferencia de tipo" en kotlin
  • Propiedad de extensión en línea Kotlin
  • Función de extensión Kotlin en propiedad mutable
  • ¿Cómo colocar una extensión de Kotlin en un file de class?