在Kotlin中使用嵌套类共享泛型类型

时间:2018-01-18 17:28:11

标签: generics kotlin inner-classes

我试图用通用类型的节点做一个简单的Dijkstra探路者。 为此,我有我的路径查找器类和嵌套数据类来帮助。 它看起来像这样

class Dijkstra<T, U: Number >(  val graph: Graph<T, U>,
                                val from: Node<T, U>,
                                val to: Node<T, U>) {

    private var nodesDistances = mutableMapOf<Node<T, U>, DijkstraDistanceHelper<T, U>>()

    init {
        graph.getNodeList().forEach { nodesDistances[it] = DijkstraDistanceHelper<T, U>(it, null, null) }

        val currentNode = from

        while (currentNode != to) {
            currentNode.getNeighborhood()?.forEach {
                if (it.destination != currentNode) {
                    //it.value type is U and properly recognized as such
                    val currentDistance = it.value + (nodesDistances[currentNode]!!.distance ?: 0)

                    if (nodesDistances[it.destination]?.distance == null
                        || nodesDistances[it.destination]!!.distance!! > currentDistance) {
                        //compilator error on the compare too, same reason I assume
                        nodesDistances[it.destination]!!.distance = currentDistance
                        nodesDistances[it.destination]!!.parentNode = currentNode
                    }
                }
            }
        }
    }

    private data class DijkstraDistanceHelper<T, U: Number>(  val node: Node<T, U>,
                                                              var distance: U?,
                                                              var parentNode: Node<T, U>?)
}

这在算法上听起来不太合理,但令我困扰的是它没有编译:编译器无法理解Dijkstra的U泛型类型与DijkstraDistanceHelper相同

这是错误的方式吗?如何强制Dijkstra的泛型类型(T和U)与DijkstraDistanceHelper相同?

1 个答案:

答案 0 :(得分:1)

无法添加抽象Number实例。如果查看文档,您将看到没有定义plus运算符。这是因为添加数字具有不同的行为,具体取决于它们是浮点数还是内部大小。

您需要提供添加U实例的方法,例如(U,U) -> U作为参数,可以在创建期间提供为Int::plus或其等效项。