【问题标题】:Kotlin. Interface as parameter科特林。接口作为参数
【发布时间】:2021-11-03 07:59:51
【问题描述】:

我将静态数据存储在枚举中。它们可以有很多,但它们具有相同的结构,由一个特殊的接口指定,以简化它们的工作。我在 Swift 中使用了类似的逻辑并且它可以工作,但是 Kotlin 不允许我使用这样的逻辑。

interface DataElement {
    val code: UInt
    val name: String
}

enum class DataEnum1: DataElement {

    Apple {
        override val code: UInt
            get() = 1u
    },

    Orange {
        override val code: UInt
            get() = 2u
    },

    Watermelon {
        override val code: UInt
            get() = 3u
    }
}

enum class DataEnum2: DataElement {

    Blueberry {
        override val code: UInt
            get() = 4u
    },

    Strawberry {
        override val code: UInt
            get() = 5u
    },

    Blackberry {
        override val code: UInt
            get() = 6u
    }
}

问题来了

fun someFun() {
  val array = DataEnum1.values()
  anotherFun(array) // TYPE MISMATCH
  //Required:
  //Array<PeripheralDataElement>
  //Found:
  //Array<DataEnum1>
}
    
fun anotherFun(items: Array<DataElement>) {
     // some logic
}

【问题讨论】:

    标签: android kotlin enums interface


    【解决方案1】:

    数组在 Kotlin 中是不变的,这意味着您不能直接将 Array&lt;SubClass&gt; 传递给接受 Array&lt;SuperClass&gt; 的函数。但是,您可以像这样定义函数以使其接受协变数组:

    fun anotherFun(items: Array<out DataElement>) {
        // ...
    }
    

    现在您的函数也接受Array&lt;SubClass&gt;

    旁注: 这自动适用于列表,因为List 在接口级别的类型参数中被定义为协变,例如interface List&lt;out T&gt;

    【讨论】:

    • 澄清一下:禁止这样做的原因是该函数可以将实现DataElement 的任何对象添加到数组中,甚至可能是DataEnum2如果数组的具体类型是Array&lt;DataEnum1&gt;.
    • 最初,我想使用 List。但是 values() 方法返回一个数组
    • @TimYumalin 您也可以使用DataEnum1.values().toList()将其转换为列表
    • @marstran 在这种情况下,使用asList() 而不是toList() 更有意义。 toList() 复制数据,asList() 只是包装数组。
    猜你喜欢
    • 2021-05-11
    • 2022-12-31
    • 1970-01-01
    • 2022-11-19
    • 2021-11-28
    • 1970-01-01
    • 1970-01-01
    • 2021-04-19
    • 1970-01-01
    相关资源
    最近更新 更多