gpt4 book ai didi

operator-overloading - 如何在不进行子类化的情况下将运算符扩展添加为特定类的上下文的一部分?

转载 作者:行者123 更新时间:2023-12-04 08:22:19 28 4
gpt4 key购买 nike

我正在尝试将运算符用于 Wicket,这非常冗长。

我最想要的功能是使用一元“+”到add()一个组件。
但它需要在每个 MarkupContainer 的上下文中工作。后人。

使用应该是这样的:

class SomePage() : WebPage() {
init {
// SomePage{} context
+Label("someLabel","Some label")
// instead of this.add(Label("someLabel","Some label"))
+object : StatelessForm<Unit>("someForm") {
init {
// StatelessForm{} context
+Label("fieldLabel","Field label")
+RequiredTextField("someField")
}
}
}
}

现在是否可以在不继承所有内容的情况下实现这一点?我想要的一些虚构的语法:
extend org.apache.wicket.MarkupContainer {
operator fun<T: Component> T.unaryPlus():T {
// add() is called as a method of a MarkupContainer instance
add(this) // this@MarkupContainer.add(this@unaryPlus)
return this
}
}
  • https://kotlinlang.org/docs/reference/extensions.html
  • https://kotlinlang.org/docs/reference/operator-overloading.html
  • 最佳答案

    使用 unaryPlus 运算符( +Component )在这种情况下更难,因为正如一元所暗示的那样,它是单操作数运算符(单输入)。不过,有一种 hacky 解决方案:

    class ExtOf<out T : MarkupContainer>(val self: T) {
    companion object {
    private val lastConfiguredContainer = ThreadLocal<ExtOf<MarkupContainer>?>()

    fun <T : MarkupContainer> configure(container: T, configurer: ExtOf<T>.() -> Any?): T {
    val currentLast = lastConfiguredContainer.get()
    try {
    val newCurrent = ExtOf(container)
    lastConfiguredContainer.set(newCurrent)
    newCurrent.configurer()
    } finally {
    lastConfiguredContainer.set(currentLast)
    }
    return container
    }
    }

    operator fun <T2 : Component> T2.unaryPlus(): T2 {
    val container = lastConfiguredContainer.get()
    container!!.self.add(this) //TODO throw a nice exception explaining how ot use the `configure`
    return this
    }
    }

    fun <T : MarkupContainer> T.configure(configurer: ExtOf<T>.() -> Any?) = ExtOf.configure(this, configurer)

    以上维护了有关上次配置的信息 MarkupContainer ThreadLocal 用于提供 add 的接收者的私有(private)变量方法。

    然后你可以写:
    class SomePage() : WebPage() {
    init {
    configure {
    +Label("someLabel", "Some label")

    +StatelessForm<Unit>("someForm").configure {
    // StatelessForm{} context
    +Label("fieldLabel", "Field label")
    +RequiredTextField<Long>("someField")
    }
    }
    }
    }

    正如我上面提到的,工作时的解决方案远非漂亮。它可能会令人困惑(就像经常重载的运算符一样),所以我建议使用常规 add像这样:
    class SomePage() : WebPage() {
    init {
    add(
    Label("someLabel", "Some label"),

    StatelessForm<Unit>("someForm").apply {
    // StatelessForm{} context
    add(
    Label("fieldLabel", "Field label"),
    RequiredTextField<Long>("someField")
    )
    }
    }
    }
    }

    我想理想情况下会有一个类似于 anko 的库但对于 wicket 。

    关于operator-overloading - 如何在不进行子类化的情况下将运算符扩展添加为特定类的上下文的一部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37338485/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com