2016-07-11 37 views
5

定義的實例我想爲kotlin 1.0.3的web框架編寫一個很好的Kotlin包裝。在這我試圖混入一個函數的請求,讓它通過使用傑克遜的JSON轉換返回一個bean。在kotlin中,如何返回通過泛型類參數

所以在我的圖書館我有以下

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

但是當我轉到使用代碼這樣

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

它錯誤說Bean的預期值是任何。我想要的是我的API像上面那樣工作,無論傳遞給asDataBean方法的通用「類」定義是返回的值的類型。

我也試過

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

以及在使其工作,但使用的代碼時,他們也給出確切的同樣的錯誤,希望改變使用代碼

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

我該如何獲得它使用傳入的類類型定義的泛型作爲參數(非常類似於所有spring api在java中的工作方式)?

+0

奇怪的是,第一個片段爲我工作好吧。你能否提供一個沒有外部依賴關係的最小自包含示例? – voddan

+0

我不知道我明白。我創建了一個github倉庫,在https://github.com/sepatel/kotlin-seed上顯示代碼。這是整個項目,希望能幫助更好地描述這個問題?它給出的錯誤是使用API​​時出現編譯錯誤,說「e:Main.kt:(23,9):期望Any類型的值 e:Main.kt:(23,34):類型推斷失敗:沒有足夠的信息來推斷參數T在樂趣 Request.asData(類型:KClass <*>):T「 – Ryba

回答

4

post功能需要route: (Request, Response) -> Any參數,這是一個功能,接受請求和響應並返回一些非空值。

當您使用lambda表達式作爲route時,其返回類型是從lambda正文的最後一個表達式推斷出來的,並且由於在Kotlin中賦值不是表達式,因此以下lambda根本沒有返回類型:

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

爲了使工作只是讓bean最後一個表達式

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

或完全不使用賦值:

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

注:我已經使用asDataBean函數的定義如下:

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

而且你可以做一個具體化的過載,它調用非物化的一個,這樣你就不必揭露所有內部:

inline fun <reified T: Any> Request.asDataBean(): T = 
    asDataBean(T::class) 

req.asDataBean<TestBean>() // usage 
+0

謝謝,我不能相信我錯誤地解釋了這樣的錯誤信息,在閱讀你的理由之後,我覺得自己像個新手一樣,謝謝關於通知的提示,我從來沒有想過這個,聽起來像最好的解決手頭的問題。 – Ryba

5

更科特林慣用的方式是使用reified type parameters

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

然後可以消耗爲:

在你的榜樣
post("/hello", { req, res -> 
    val bean = req.bodyAs<TestBean>() 
    res.body("Ok") 
}) 
+1

爲了內聯你必須讓所有的變量公開可用,在這種情況下,映射器是私人定義在庫中,所以內聯不起作用。另外,我已經試圖按照你提到的方式,通過將mapper公開並使其通過,並且它仍然不是消耗品,正如你所描述的,給出了期望的任何類型的編譯器錯誤。 – Ryba

+0

創建了一個分支https://github.com/sepatel/kotlin-seed/tree/reified來證明即使被指定,它也不起作用,在使用時給出「期望值爲任意類型」錯誤。 – Ryba

+0

@Ryba the'post(「/ hello」,{res,req-> ...'lamba參數必須返回'Any'。Kotlin中的賦值不是一個表達式,因此它沒有任何價值。返回值 – miensol

相關問題