gpt4 book ai didi

design-patterns - Kotlin 责任链模式与泛型

转载 作者:行者123 更新时间:2023-12-02 08:05:07 24 4
gpt4 key购买 nike

使用责任链模式时,我遇到了一个问题,即期望下一个链元素与第一个元素具有相同的通用类型。我知道为什么发生这种情况:第一个处理程序期望第二个处理程序使用泛型类型“Apple”。我只是不知道如何解决它。

有关于如何操作的答案 handle it in java here ,但是由于 java 没有具体化的类型,而且所有这些方法在 Kotlin 中都应该有所不同,对吗?

我想到了不同的选择:

  • 不要使用泛型 - 会导致将集合类型转换为特定的子类型并且看起来不干净
  • 尝试使用具体化类型(如何?)

  • 为了说明这个问题,我在下面发布了一个演示代码。
    data class Apple(val name:String, val color:Int) 
    data class Orange(val circumference:Double)

    object Main{
    @JvmStatic
    fun main(args: Array<String>) {
    val first = FirstHandler()
    val second = SecondHandler()
    first.setNextHandler(second) // !!! wrong type here since <Apple> is expected
    first.process()
    }
    }

    abstract class ChainHandler<T>{
    protected var nextHandlerInChain:ChainHandler<T>? = null
    fun setNextHandler(handler: ChainHandler<T>): ChainHandler<T> {
    this.nextHandlerInChain = handler
    return handler
    }

    abstract fun peel(): Collection<T>
    abstract fun process():MutableMap<String,Any> }

    class FirstHandler : ChainHandler<Apple>() {
    override fun peel(): Collection<Apple> {
    return Collections.emptyList<Apple>()
    }
    override fun process(): MutableMap<String, Any> {
    val peeledApples = peel()
    val map = nextHandlerInChain?.process()
    map?.put("apples",peeledApples) ?:kotlin.run {
    val map = mutableMapOf<String,Any>()
    map.put("apples",peeledApples)
    }
    return map!!
    } }

    class SecondHandler : ChainHandler<Orange>() {
    override fun peel(): Collection<Orange> {
    return Collections.emptyList<Orange>()
    }
    override fun process(): MutableMap<String, Any> {
    val peeledOranges = peel()
    val map = nextHandlerInChain?.process()
    map?.put("oranges",peeledOranges) ?:kotlin.run {
    val map = mutableMapOf<String,Any>()
    map.put("oranges",peeledOranges)
    }
    return map!!
    }
    }

    最佳答案

    Kotlin 有一种叫做星形投影的东西,可以在这里帮助你。它基本上告诉编译器你并不真正关心 ChainHandler 的类型。你得到。您可以用它来制作您的 setNextHandler编译,像这样:

    abstract class ChainHandler<T>{
    // Note the star projection here
    protected var nextHandlerInChain: ChainHandler<*>? = null

    // Defining a type parameter S, so that the return type is equal to the input type.
    fun <S> setNextHandler(handler: ChainHandler<S>): ChainHandler<S> {
    this.nextHandlerInChain = handler
    return handler
    }

    ...
    }

    您可以在此处阅读有关星形投影的更多信息: https://kotlinlang.org/docs/reference/generics.html#star-projections

    至于具体化类型参数:具体化类型参数仅适用于内联函数。不适用于类的类型参数。

    关于design-patterns - Kotlin 责任链模式与泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52487069/

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