簡體   English   中英

如何在Kotlin的實例字段中存儲已知類型的數據?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM