2011-02-13 86 views
3

如何編寫從Array[_]List[_]類型的隱式轉換?我嘗試了以下,但它似乎並沒有工作。將數組隱式轉換爲列表

scala> implicit def arrayToList[A : ClassManifest](a: Array[A]): List[A] = a.toList 
<console>:5: error: type mismatch; 
found : Array[A] 
required: ?{val toList: ?} 
Note that implicit conversions are not applicable because they are ambiguous: 
both method arrayToList in object $iw of type [A](a: Array[A])(implicit evidence$1: ClassManifest[A])List[A] 
and method genericArrayOps in object Predef of type [T](xs: Array[T])scala.collection.mutable.ArrayOps[T] 
are possible conversion functions from Array[A] to ?{val toList: ?} 
     implicit def arrayToList[A : ClassManifest](a: Array[A]): List[A] = a.toList 
                     ^

回答

6
implicit def arrayToList[A](a: Array[A]) = a.toList 

似乎按預期方式工作。我的猜測是,Predef中已經有一個genericArrayOps,它具有隱含從Array[T] -> ArrayOps[T]轉換的簽名,ArrayOps[T]有一個方法.toList(): List[T]。你的方法有簽名Array[T] -> List[T],這也使得方法.toList[T]可用。該機構正在要求對該簽名進行隱式轉換。編譯器不知道使用arrayToList會使該方法進入無限循環,因此出現歧義錯誤。但是,類型推斷返回類型似乎能夠解決此問題。 Implicits解決方案看起來不太適合類型推理。

另外值得注意的是,由於已經有一個隱式轉換,默認情況下會得到你想要的,所以不需要從ArrayList的隱式轉換。

+0

命名約定`XxxOps`總是暗示你看到'Xxx`類型的延伸方法。 – 2011-02-13 11:48:00

+0

這對我很有用。我有一個可能爲null的數組(從一個JDBC調用返回,所以`Option`不是一個選項),並使用你的解釋/解決方法,我可以創建一個隱式來處理它:`implicit def nullableArrayToList [T]( array:Array [T])Option(array).fold(List.empty [T]){_.toList}` – Raman 2014-05-13 17:56:55

5

沒有必要爲Manifest或陣列轉換ClassManifest,作爲Array是一個「收藏」型在JVM上得到特殊待遇,不進行類型擦除。

這意味着,你可以明顯的/瑣碎的方法去,不需要掛羊頭賣狗肉:

implicit def arrayToList[A](arr: Array[A]) = arr.toList 

但有一個問題......既然.toList已經是這樣一個平凡的操作,你通過使獲得什麼它隱含?