2011-03-01 53 views
3

Java API中定义的方法:有麻烦java.util.Collection中的#创建斯卡拉代表指定者

interface Collection<T> { 
    <X> X[] toArray(X[] a); 
} 

我试图做这样的事情在斯卡拉:

class SCollection[T] extends Collection[T] { 
    val queue = new LinkedBlockingQueue[T] 

    def toArray[X](a: Array[X]) : Array[X] = queue.toArray(a) 
} 

我为了清楚起见,在界面中省略了其他方法。编译器抱怨:

overloaded method value toArray with alternatives: 
    [T](x$1: Array[T with java.lang.Object])Array[T with java.lang.Object] <and> 
()Array[java.lang.Object] 
cannot be applied to (Array[X]) 
    def toArray[X](a: Array[X]) : Array[X] = queue.toArray(a) 
               ^

如何成功覆盖toArray(..)方法?

回答

4

编译器抱怨,因为你必须确保你不传递像例如Array[Int](它映射到Java中的int[])。

你可以写你的方法是这样的:

override def toArray[X](a: Array[X with AnyRef]) = queue.toArray[X](a) 
+0

这只是产生一个不同的编译器错误:类型'Array [X with AnyRef]'的表达式不符合期望的类型'Array [X]' – 2014-03-10 06:46:51

1

数组是唯一的物化“收集”的JVM类型,所以建立你需要知道在运行时的确切类型的数组。擦除后不是一件容易的事情...

如果你看看如何在Scala集合上实现toArray,你会发现它使用Manifest来恢复擦除类型信息。你基本上需要复制这个,并确保你的类型T有一个Manifest。

但是,您为什么首先要实施这个课程?如果您尝试创建自定义集合类,那么您会发现添加诸如CanBuildFrom之类的功能很快就会变得非常具有挑战性。如果你只是想要一个包装器提供给其他库的java Collection,那么我建议使用JavaConvertors。如果你不需要互操作,那么根本就没有理由实现Collection,因为Scala有一个独特的集合框架,并且通常避免了Java的集合,这些集合被打破用于完全类型安全的函数式编程。