首页 文章

Kotlin:通用函数作为返回类型?

提问于
浏览
1

在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() }

正如目前的答案所示;我没有得到通用函数,如果我调用 prefixer<Foo>("") ,我得到 (String, KClass<Foo>) -> 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() })
}

请注意,该项目作为闭包进入 . 现在我想在不同的插件中重用该帮助器,因此我想使用工厂为不同的项目实例创建此函数 .

3 回答

  • 3

    不,这是不可能的(据我所知) . 这种类型的技术术语是“更高级的类型”,很少有语言支持它们,在JVM上我只知道Scala .

    如果有人在没有像 Factory 这样的界面的情况下问我同样的问题,我建议创建这个界面作为解决方法 .

  • 2

    你几乎正确地做到了 . 您只需要直接在 prefixer 函数中定义通用部分 .

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

    根据您的实际实现,您可以查看reified关键字 .

  • 0

    以下行确实编译:

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

    首先,通用减速应该在fun关键字之后 .

    然后必须将其声明为Any类型 . 默认是Any?但KClass只需要任何 .

相关问题