[英]How can I store reified type data in instance fields in Kotlin?
我正在為一個庫編寫一個DSL,我想使用這樣的具體類型參數提供類型元數據:
val config = Config.create()
.consumerFor<MyType>{
// consume
}
我的問題是,我只能用reified
關鍵字inline
函數和一個inline
函數,我不能用這樣的實例字段:
inline fun <reified T> consumerFor(consumer: (T) -> Unit) {
consumers.put(T::class.java, consumer)
return this
}
因為我收到一個錯誤:
Public-API內聯函數無法訪問非公共API的私有最終val消費者...
到目前為止,我似乎無法使用最有用的reified類型參數。 這有解決方法嗎?
公共inline
函數不能直接使用private
聲明,因為當在類外部的調用站點內聯時,用法將具有不正確的訪問級別(在JVM上,無法從外部訪問類的private
成員)。
您可以做的是使用Kotlin中的internal
可見性 :在JVM上,具有此可見性修飾符的成員將被編譯為公共成員,其名稱被破壞(因此仍然可見但不容易從Java調用)和Kotlin編譯器至少會控制Kotlin代碼的用法。
有一些方法可以從public inline fun
訪問internal
成員,請參閱此問題:( 鏈接)
在您的特定情況下,我更喜歡使用@PublishedApi
:
private val consumers = mutableMapOf<Class<*>, Any>()
@PublishedApi
internal fun <T> putConsumer(clazz: Class<out T>, consumer: (T) -> Unit) {
consumers.put(clazz, consumer)
}
inline fun <reified T> consumerFor(noinline consumer: (T) -> Unit): C {
putConsumer(T::class.java, consumer)
return this
}
或者,如果您不介意使用@PublishedApi
公開consumers
,那么您可以按如下方式進行:
@PublishedApi
internal val consumers = mutableMapOf<Class<*>, Any>()
inline fun <reified T> consumerFor(noinline consumer: (T) -> Unit): C {
consumers.put(T::class.java, consumer)
return this
}
如果您需要reified類型參數的所有內容都是為了反映其java類,那么您可以使用帶有附加Class<T>
參數的非內聯重載進行管理。
inline fun <reified T> consumerFor(noinline consumer: (T) -> Unit) =
consumerFor(T::class.java, consumer)
fun <T> consumerFor(key: Class<T>, consumer: (T) -> Unit) = apply {
consumers.put(key, consumer)
}
這樣您就沒有公開consumers
有效發布的財產。 獎勵點是您也可以從Java調用非內聯重載。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.