簡體   English   中英

Kotlin:通用函數作為返回類型?

[英]Kotlin: Generic function as return type?

在 Kotlin 中,是否可以將泛型函數類型聲明為函數的返回類型?

我想要實現的在 Java 中看起來像這樣:

interface Factory {

    static Factory INSTANCE = new FactoryImpl();

    <T> T create(String name, Class<T> type);

}

class PrefixedFactory implements Factory {
    private final String prefix;

    PrefixedFactory(String prefix) {
        this.prefix = prefix;
    }

    @Override
    public <T> T create(String name, Class<T> type) {
        return Factory.INSTANCE.create(prefix + name, type);
    }
}

(請注意,在示例中,我使用靜態字段訪問 Factory 實例以避免將泛型函數作為參數傳遞,這會在 Kotlin 中出現其自身的問題)。 我想將前綴轉換為 kotlin 函數,但似乎不可能將泛型函數聲明為返回類型:

fun prefixer(prefix: String): <T> (String, KClass<T>) -> T { TODO() }

這當然不能編譯。 在我看來,與 Java 的功能接口相比,這是一個限制。 有沒有辦法做到這一點,或解決方法?

(編輯)澄清

我希望實際結果函數是通用的。 如果我這樣做

fun <T: Any> prefixer(prefix: String): (String, KClass<T>) -> T { TODO() }

正如目前的答案所暗示的那樣; 我沒有得到通用函數,而是得到(String, KClass<Foo>) -> Foo如果我調用prefixer<Foo>("") 所以這個函數只能用Foo調用,而在這種情況下工廠函數prefixer是通用的,結果不是。 我希望能消除誤解。

我的用例是在 Gradle 插件中,我在其中編寫了一個類似於此的輔助方法,該方法將一些默認值應用於創建的每個任務:

val myPrefix = "..."
val project: Project = <from context>
fun <T: Task> String.task(type: KClass<T>, doConfig: T.() -> Unit) {
  project.tasks.create("$prefix$this", type.java, { it.doConfig() })
}

請注意,該項目以關閉形式出現。 現在我想在不同的插件中重用該助手,所以我想使用工廠為不同的項目實例創建這個函數。

你幾乎做對了。 您只需要直接在prefixer函數中定義泛型部分即可。

fun <T: Any> prefixer(prefix: String): (String, KClass<T>) -> T { TODO() }

根據您的實際實現,您可以查看reified關鍵字。

以下行確實編譯:

fun <T : Any> prefixer(prefix: String): (String, KClass<T>) -> T = TODO()

首先,通用減速應該緊跟在 fun 關鍵字之后。

然后它必須聲明為 Any 類型。 默認是任何? 但 KClass 只接受 Any。

盡管我對閱讀@Alexey 的回答感到失望,但我發現了一種利用 Kotlin 運算符的更簡化的解決方法。 以下使它在使用時看起來更像一個 lambda:

private class Prefixer(private val: String) {
    operator fun <T> invoke(name: String, type: Class<T>): T {
        TODO()
    }
}

要使用它:

val createMy = Prefixer("MyPrefix")
val result = createMy("Configuration", Configuration::class.java)

如有必要,請隨意替換為KClass 我實際上是為了稍微不同的目的使用它。

不,這是不可能的(據我所知)。 這種類型的技術術語是“高級類型”,很少有語言支持它們,在 JVM 上我只知道 Scala。

如果有人在沒有像Factory這樣的界面的情況下問我同樣的問題,我建議完全創建這個界面作為解決方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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