繁体   English   中英

Kotlin-通用功能

[英]Kotlin- Generic functions

我目前正在尝试编写一个dsl,以便轻松构建Swing用户界面。 为了实现这一目标,而不必支持所有类型的组件,我想制作一个通用函数来添加一个容器,在我的情况下,这意味着扩展JPanel所有内容。

我最终得到的是:

fun <T : JPanel> container(containerComponent: T = JPanel(), constraints: LC = LC(), setup: T.() -> Unit): T {
    containerComponent.setup()
    containerComponent.layout = MigLayout(constraints)
    return containerComponent
}

但是,在第一行的第一个参数上,我得到一个错误Type mismatch: Required T, but found JPanel ,但是我真的不明白为什么,因为我指定T将是扩展JPanel东西。

正如@shmosel已经指出的那样, T可能仍然是JPanel之外的东西,这将导致JPanel不满足T

这是一个可能的示例:

    val setup: JPanelExtendingClass.() -> Unit = {
        //Perform actions on splitpane
    }
    container(constraints = LC(), setup = setup)

这将导致TJPanel不符合的JPanelExtendingClass

因此,我最终将整个过程分为两种方法,一种专门用于JPanel

fun panel(constraints: LC = LC(), setup: JPanel.() -> Unit): JPanel {
    return container(JPanel(), constraints, setup)
}

另一个用于扩展JPanel

fun <T : JPanel> container(containerComponent: T, constraints: LC = LC(), setup: T.() -> Unit): T {
    containerComponent.setup()
    containerComponent.layout = MigLayout(constraints)
    return containerComponent
}

但是,这个没有定义任何默认组件。

您想要一个可以将任何JPanel类型作为参数的函数,如果未指定参数值,则它将为JPanel。

现在,假设您以这种方式调用该函数:

container<JPanelExtendingClass> { ... }

在这种情况下, containerComponent参数的类型将为JPanelExtendingClass ,值将为JPanel()

JPanel不是JPanelExtendingClass的子类,因此编译器会拒绝它。

在这里,您实际上不需要通用该函数,可以将函数更改为

fun container(containerComponent: JPanel = JPanel(), constraints: LC = LC(), setup: JPanel.() -> Unit): JPanel {...}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM