close

今天在 Java convert to Kotlin 的工程中

想到了這個問題

我們一定常常遇到 Java 泛型的寫法吧?

比如最常見的 ArrayList<T> 

或是在 method 中也會出現

如 Gson 的 fromJson() 原碼

public <T> T fromJson(String json, Class<T> classOfT) 
  throws JsonSyntaxException {
  
  Object object = fromJson(json, (Type) classOfT);
  return Primitives.wrap(classOfT).cast(object);
}

 

那 Kotlin 中的泛型如何表現呢?

就以 Gson 做為例子好了

在傳輸資料時,Gson 想必是大家常用的工具吧?

假設一個情境,我登入了

然後把 UserData 存進 SharedPerferences 之中

其中 Object、String 之間的相互轉換就用 Gson 來做

 

然後現在我們要取 UserData 出來了

會用到下面的 Java method

public <T> T getObject(String keyName, Class<T> clazz) {
    return new Gson().fromJson(getString(keyName), clazz);
}

 

可以看到我們利用泛型來決定 return 的 class 是什麼

這很好理解

那到了 Kotlin 我們要如何寫出一樣的功能呢?

Kotlin 一樣有泛型,位置是在 fun name 前面

寫起來像這樣

fun <T>getObject(keyName: String):T 
    = Gson().fromJson(getString(keyName),T::class.java)

 

但這樣寫會發生錯誤

Cannot use 'T' reified type parameter.

為什麼呢?

因為 T 是虛的,他沒辦法具現化

 

這時候就要提到兩個關鍵字了 inline & reified

說到 inline 就要提到 C 語言

因為這是從 C 搬過來的概念

加入 inline 的 fun 就叫做「內聯函數」

它可以節省每次調用函數帶來的額外時間開支

相關知識可點此了解

或是點此至官網閱讀 inline & reified 文件

 

回正題

reified 要搭配 inline 才可以使用

否則會報錯

Only type parameters of inline function can be reified.

加入之後會變成這樣

inline fun <reified T>getObject(keyName: String):T 
    = Gson().fromJson(getString(keyName),T::class.java)

 

這麼一來就可以使用了

調用方式如下

getObject<UserData>(KEY_USER_DATA)

 

 

 

資料來源:

https://kotlinlang.org/docs/reference/inline-functions.html

https://zh.wikipedia.org/wiki/%E5%86%85%E8%81%94%E5%87%BD%E6%95%B0

 

 

 

 

 

 


arrow
arrow

    顏澤偉 發表在 痞客邦 留言(0) 人氣()