2011-03-01 91 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的集合,這些集合被打破用於完全類型安全的函數式編程。