我正在使用现有的
java库练习scala.将Array [T]传递给func(Array [U])是很常见的,其中T <:U.例如:
Java的:
public class Quick { ...
public static void sort(Comparable[] a) { ... }
}
public class Edge implements Comparable<Edge> { ... }
public class EdgeWeightedGraph { ...
public Iterable<Edge> edges() { ... }
}
斯卡拉:
class Kruskal(private val G: EdgeWeightedGraph) {
init()
private def init() = {
val es = G.edges().asScala.toArray
/* **Error** Type mismatch,
* expected: Array[Comparable[_]],
* actual: Array[Edge]
*/
Quick.sort(es)
...
}
}
我相信这是因为Array是不变的.这是我试图绕过这一点,但它看起来很丑陋和低效:
val es = G.edges().asScala.map(_.asInstanceOf[Comparable[_]]).toArray)
Quick.sort(es)
我该如何以更好的方式做到这一点?
最佳答案 数组是不变的,因为它们是可变的.如果它们不是不变的,你可以做类似的事情
class Fruit
class Apple extends Fruit
class Orange extends Fruit
val apples:Array[Apple] = Array(new Apple())
val fruits:Array[Fruit] = apples
fruits.update(0,new Orange)
val apple:Apple = apples(0) //<= epic fail I now have an orange as an apple ?
我能想到的唯一方法是将集合复制到等效的不可变集合(collection.immutable.Seq的子类型)
class Fruit
class Apple extends Fruit
class Orange extends Fruit
val apples:Array[Apple] = Array(new Apple())
val fruits:collection.immutable.Seq[Fruit]=apples.toList // or apples.toIndexedSeq
然后得到一个不可变的集合,你可以得到差异
在您的具体示例中,您可以更改
val es = G.edges().asScala.toArray
至
val es = G.edges().asScala.toIndexedSeq
但是你必须让QuickSort签名接受我猜的IndexedSeq.没有更多代码就很难说出后果……