2011-02-13 84 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已经是这样一个平凡的操作,你通过使获得什么它隐含?