Java API中定义的方法:
interface Collection<T> {
<X> X[] toArray(X[] a);
}
我尝试在Scala中执行类似的操作:
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(..)方法?
答案 0 :(得分:4)
编译器抱怨,因为你必须确保不传递原始数组,例如Array[Int]
(在Java中映射到int[]
。)
你可以这样编写你的方法:
override def toArray[X](a: Array[X with AnyRef]) = queue.toArray[X](a)
答案 1 :(得分:1)
数组是jvm上唯一的已知的“集合”类型,因此要构建数组,您需要在运行时知道确切的类型。擦除后不是一件容易的事情......
如果您查看在Scala集合上如何实现toArray
,您会看到它使用Manifest
来恢复已擦除的类型信息。您基本上需要复制此内容,并确保您的类型T
可以使用清单。
但是,你为什么要首先实现这个课程呢?如果您正在尝试创建自定义集合类,您会发现添加CanBuildFrom
等功能很快就会变得极具挑战性。如果您只是希望包装器向其他库提供java Collection
,那么我建议使用JavaConvertors
。如果你不需要互操作,那么根本就没有理由实现Collection
,因为Scala有一个独特的集合框架,并且通常避免使用Java的集合,这些集合在完全类型安全的函数式编程中被破坏。